簡體   English   中英

fflush() 總是返回 0 但將 errno 設置為 11(資源暫時不可用)

[英]fflush() always returns 0 but sets errno to 11 (resource temporarily unavailable)

每當我調用vasprintf()函數時, errno都會設置為 11(資源暫時不可用)。 但是,似乎一切正常。 為了更好地理解錯誤的來源,我在 uclibc 中找到了vasprintf()的實現並將其放入我的程序中。 我發現fflush()errno為 11。但是,所有跡象都表明代碼運行正常。 例如, fflush()的返回值是0 文件關閉后, open_memstream()size值會正確更新。 輸出緩沖區已正確更新。 我還在無限循環中調用了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;

}

這是上面程序的輸出。

# /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

#

這是 C 標准的微妙之處。 大多數庫函數即使成功也允許將errno為非零值。 您應該只在函數以其他方式報告失敗后查看errno

兩個重要的注意事項:

  • 有極少數函數可能通過將errno為非零值來報告失敗; 最突出的是strto*函數。 要正確調用這些函數,您必須在調用它們之前自己將errno為零,然后立即檢查它是否變為非零。

  • 該標准保證 C 庫函數永遠不會errno為零。

標准語: N1570 第 7.5 節第 3 段

程序啟動時,初始線程中的errno 的值為零(其他線程中的errno 的初始值是不確定的值),但從未被任何庫函數設置為零。 errno 的值可以通過庫函數調用設置為非零,無論是否存在錯誤,前提是 [特定函數的文檔沒有另外說明]。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM