每当我调用该vasprintf()函数errno时,该函数都会设置为 11(资源暂时不可用)。但是,似乎一切正常。为了更好地理解错误的来源,我vasprintf()在 uclibc 中找到了一个实现并将其放入我的程序中。我发现 isfflush()设置errno为 11。但是,所有迹象都表明代码运行正常。例如,来自的返回值fflush()是0。文件关闭后,的size值open_memstream()会正确更新。输出缓冲区已正确更新。我还在output()无限循环中调用了该函数以查看是否有任何内存泄漏,但在几千个循环中我没有看到内存增加。
如果文件被关闭并写入数据,是否真的有错误需要解决?
#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;
}
Run Code Online (Sandbox Code Playgroud)
这是上面程序的输出。
# /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
#
Run Code Online (Sandbox Code Playgroud)
这是 C 标准的微妙之处。大多数库函数即使成功也被允许设置errno为非零值。您应该只在函数已经以其他方式报告失败后查看。errno
两个重要的注意事项:
很少有函数只能通过设置errno为非零值来报告失败;最突出的是strto*功能。要正确调用这些函数,您必须errno在调用它们之前自己设置为零,然后立即检查它是否变为非零。
该标准保证 C 库函数永远不会设置errno为零。
程序启动时,初始线程中的errno 的值为零(其他线程中的errno 的初始值是不确定的值),但从未被任何库函数设置为零。errno 的值可以通过库函数调用设置为非零,无论是否存在错误,前提是 [特定函数的文档没有另外说明]。