On 12/14/19 1:37 AM, Florian Weimer wrote:
* Vineet Gupta:
Here's a simple test case which shows the
problem:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void main(void)
{
const char *this_func = "finite";
char *test_name;
errno = 0;
if (asprintf (&test_name, "%s (%s)", this_func,
"my-str") == -1)
abort ();
printf("%d\n", errno); // <-- prints 11
}
The errno unconditionally being set to EAGAIN seems to have been
introduced in commit 568ceebf6adfc58c64a95133311268db6 ("Fix
infinite loop when fopencookie custom write returns 0 on error")
bakc in 2016.
For functions specified by standards, successful calls can alter errno
unless specified otherwise. asprintf is not a standardized function,
but it is reasonable to expect that a similar rule applies.
Right, but ...
1. Don't those standards specify the exact errno for specific scenarios and that
typically errno won't be changed to !0 if there was no error.
2. The EAGAIN being returned can be seen as "leaking" out of internal details
of
the ensuing call stack.
3. This breaks the way uclibc test harness works. It clears the errno at the start
of a call sequence and in the end when notices the change it trips. It expects the
errno to be set (or not set) by the math routines and asprintf changing them trips
it. glibc test harness is no different - it would have failed in similar way had
similar errno fudging existed there !
At any rate the fix is simple to only change errno in case of a failure.
Thx,
-Vineet