Whenever I call the vasprintf()
function errno
gets set to 11 (resource temporarily unavailable). However, it appears that everything is functioning correctly. To better understand the source of the error I found an implementation of vasprintf()
in uclibc and put it in my program. What I found is that the fflush()
is setting errno
to 11. However, all indications are that the code is functioning correctly. For example, the return value from fflush()
is 0
. The size
value for open_memstream()
is updated correctly after the file is closed. The output buffer is updated correctly. I also called the output()
function in an infinite loop to see if any memory was leaking, but I saw no increase in memory over a few thousand loops.
If the file was closed and the data was written, is there really an error to resolve?
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
void output(int type, const char *fmt, ...)
{
FILE *f;
size_t size;
int rv = -1;
int fclose_return = 5;
int fflush_return = 5;
va_list ap;
char *output_str_no_prefix = NULL;
va_start(ap, fmt);
// vasprintf(&output_str_no_prefix, fmt, ap);
if ((f = open_memstream(&output_str_no_prefix, &size)) != NULL) {
rv = vfprintf(f, fmt, ap);
errno = 0;
printf("%s: errno(%d): %s -- Return Value: %d\n",
__func__, errno, strerror(errno), fflush_return);
fflush_return = fflush(f);
printf("%s: errno(%d): %s -- Return Value: %d\n",
__func__, errno, strerror(errno), fflush_return);
errno=0;
fclose_return = fclose(f);
printf("%s: errno(%d): %s -- Return Value: %d\n",
__func__, errno, strerror(errno), fclose_return);
if (rv < 0) {
free(output_str_no_prefix);
output_str_no_prefix = NULL;
} else {
output_str_no_prefix = realloc(output_str_no_prefix, rv + 1);
}
}
va_end(ap);
printf ("%s\n", output_str_no_prefix);
free(output_str_no_prefix);
}
int main () {
output(0, "Hello! -- %d\n", 4);
return 0;
}
Here is the output for the program above.
# /data/HelloWorld
output: errno(0): Success -- Return Value: 5
output: errno(11): Resource temporarily unavailable -- Return Value: 0
output: errno(0): Success -- Return Value: 0
Hello! -- 4
#
This is a subtlety of the C standard. Most library functions are allowed to set errno
to a nonzero value even if they succeed. You should only look at errno
after a function has already reported failure in some other way.
Two important notes:
There are a very few functions that may report failure only by setting errno
to a nonzero value; the most prominent ones are the strto*
functions. To call these functions correctly you have to set errno
to zero yourself right before calling them, then check whether it became nonzero immediately afterward.
The standard guarantees that C library functions never set errno
to zero.
Standardese: N1570 section 7.5 paragraph 3
The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided [the documentation for the specific function doesn't say otherwise].