fflush() 总是返回 0 但将 errno 设置为 11(资源暂时不可用)

Eri*_*icB 1 c uclibc fflush

每当我调用该vasprintf()函数errno时,该函数都会设置为 11(资源暂时不可用)。但是,似乎一切正常。为了更好地理解错误的来源,我vasprintf()在 uclibc 中找到了一个实现并将其放入我的程序中。我发现 isfflush()设置errno为 11。但是,所有迹象都表明代码运行正常。例如,来自的返回值fflush()0。文件关闭后,的sizeopen_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)

zwo*_*wol 5

这是 C 标准的微妙之处。大多数库函数即使成功也被允许设置errno为非零值。您应该只在函数已经以其他方式报告失败后查看。errno

两个重要的注意事项:

  • 很少有函数只能通过设置errno为非零值来报告失败;最突出的是strto*功能。要正确调用这些函数,您必须errno在调用它们之前自己设置为零,然后立即检查它是否变为非零。

  • 该标准保证 C 库函数永远不会设置errno为零。

标准语:N1570 第 7.5 节第 3 段

程序启动时,初始线程中的errno 的值为零(其他线程中的errno 的初始值是不确定的值),但从未被任何库函数设置为零。errno 的值可以通过库函数调用设置为非零,无论是否存在错误,前提是 [特定函数的文档没有另外说明]。