在CentOS7中运行C程序,遇到errno 9(Bad file descriptor)怎么办?

Run a C program in CentOS7, what should I do if I encounter errno 9 (Bad file descriptor)?

提问人:czg 提问时间:1/23/2023 更新时间:1/24/2023 访问量:66

问:

在下面的代码中,我将打开一个文件并编写一些内容。
由于程序在多个线程上并发运行,因此 fopen 函数执行完后log_fd的值可能为 NULL
然后,程序崩溃并退出。

static void __log_prt__(const char *fmt, va_list ap)
{   
    // omitted code ...

    FILE *log_fd = fopen(def_log_file, "a");

    // omitted code ...

    fclose(log_fd);
}

这将导致错误 9:错误的文件描述符
我修改了程序以遍历 fopen 函数,直到其返回值不再为 NULL,就像下面的代码一样:

static void __log_prt__(const char *fmt, va_list ap)
{   
    // omitted code ...

    FILE *log_fd = fopen(def_log_file, "a");
    while (log_fd == NULL) {
        log_fd = fopen(def_log_file, "a");
    }

    // omitted code ...

    fclose(log_fd);
}

这样,程序将不再出现错误 9 导致的崩溃。
现在我有一个问题,这是正确的做法吗?有没有更合理的方法?

c fopen errno

评论

6赞 Some programmer dude 1/23/2023
为什么不添加适当的错误处理呢?您知道这可能会失败并返回空指针,但正确的解决方案几乎永远不要忙于等待,直到可以打开(可能永远不会)。相反,优雅地失败,或者最坏的情况是告诉用户并退出程序。fopen
4赞 Allan Wind 1/23/2023
为什么并发意味着 fopen 可能会失败?只是想知道。

答:

5赞 Harith 1/24/2023 #1
FILE *log_fd = fopen(def_log_file, "a");
    while (log_fd == NULL) {
        log_fd = fopen(def_log_file, "a");
    }

这种方法似乎非常乐观。在手册页中,我统计了大约 42 种可能导致失败的不同错误情况。fopen ()

如果退货,则不能保证召回它会神奇地修复最初导致其失败的条件。fopen ()NULL

记得:

  • 失败总是一种选择。
  • 快速失败、早期失败和经常失败。
  • 不要用安全来换取任何东西。

[1] — 其中包括 (Error No Memory),此时您应该中止。ENOMEM

评论

1赞 czg 1/25/2023
谢谢,我在程序中添加了错误处理逻辑,该逻辑为 fopen 函数返回 NULL。