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
errnoto a nonzero value even if they succeed. You should only look aterrnoafter 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
errnoto a nonzero value; the most prominent ones are thestrto*functions. To call these functions correctly you have to seterrnoto zero yourself right before calling them, then check whether it became nonzero immediately afterward.The standard guarantees that C library functions never set
errnoto zero.Standardese: N1570 section 7.5 paragraph 3