代码之家  ›  专栏  ›  技术社区  ›  Edward

使用stdio的陷阱是什么。h文件*流是通过fork继承的吗?

  •  0
  • Edward  · 技术社区  · 7 年前

    我编写了一个(过于简单的)包装器,在子进程中执行另一个进程 过程子进程在调用exec()之前关闭(或重定向)标准错误。但是,如果exec()失败,我希望在父进程的标准错误上打印一条错误消息。

    下面是我目前的解决方案。在分叉之前重复标准错误。 手柄(我知道,就目前而言,这个计划没有什么意义,但我 只保留了我的问题的相关部分。)

    #include <unistd.h>
    #include <stdio.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
        int status;
        FILE *log = fdopen(dup(2), "w");
        switch (fork()) {
            case -1:
                fprintf(log, "fork: %s\n", strerror(errno));
                break;
            case 0:
                close(2);
                execvp(argv[1], &argv[1]);
                fprintf(log, "execvp: %s\n", strerror(errno));
                break;
            default:
                wait(&status);
                break;
        }
        return 0;
    }
    

    FILE * 变量 log , 标准,XSH, Sections 2.5 and 2.5.1 fflush(log) 如果碰巧缓冲了标准错误,则在fork之前。是这样吗?还有其他陷阱需要注意吗?

    用于控制流的文件对象的地址可能是重要的; 起初的

    我能把这个理解为 FILE 使用

    我应该补充一点,我不打算在双方之间的家长流程中做任何事情 fork()和wait()。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Shachar Shemesh    7 年前

    除了需要 fflush 在使用fork之前,还应该考虑标准错误可能不是控制台/管道,而是常规文件的情况。

    如果您从两个文件描述符(这是您的父母和孩子现在拥有的)写入常规文件,则写入可能会相互重叠。如果发生这种情况,您可能会丢失信息。

    fcntl(F_SETFL) O_APPEND 模式在这种模式下,两个进程可以写入同一个文件,而不会相互覆盖。

    即使在O_APPEND中,如果写入太大,输出也可能重叠。因为您使用的是缓冲IO(这是什么 FILE* 是),这不太可能,但并非不可能。在这一点上,你最好的选择就是抓住这个机会,并且 相对频繁,因此将缓冲区发送到 write 不是太大。