我写了一个(简单的)包装器,该包装在孩子中执行另一个过程过程。儿童进程在调用exec()之前关闭(或重定向)标准错误。但是,如果exec()失败,我希望在父进程的标准错误上打印一条错误消息。
以下是我当前的解决方案。我dup()在叉子之前进行标准错误。由于我希望能够进行格式I/O,因此我在重复的处理。(我知道,就目前而言,这个程序毫无意义,但是我有仅保留我的问题的相关部分。)
#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: %sn", strerror(errno));
break;
case 0:
close(2);
execvp(argv[1], &argv[1]);
fprintf(log, "execvp: %sn", strerror(errno));
break;
default:
wait(&status);
break;
}
return 0;
}
我的问题现在是:使用FILE *
变量log
的陷阱是什么,在父母和子过程中?我已经阅读了IEEE STD 1003.1-2008标准,XSH,第2.5和2.5.1节("文件描述符和标准I/O流的相互作用"),并且据我了解,这应该有效,除了我可能需要在叉子之前添加fflush(log)
,如果标准错误恰好被缓冲。那是对的吗?还有其他要注意的陷阱吗?
另外,第2.5节中相同的标准状态
用于控制流的文件对象的地址可能很重要; 文件对象的副本不一定要代替 原始。
我可以认为这意味着跨叉()继承的 FILE
对象是安全的使用?
我应该补充一点,我不打算在父程过程中做任何事情fork()和wait()。
除了在叉子之前需要fflush
之外,您还应考虑标准错误可能不是控制台/管道,而是常规文件的情况。
如果您从两个文件描述符中写入常规文件(这就是您的父母和孩子现在的内容),则写作可能会互相重叠。如果发生这种情况,您可能会丢失信息。
我建议使用fcntl(F_SETFL)
确保文件描述符处于O_APPEND
模式。在该模式下,两个进程可以写入同一文件而不相互覆盖。
即使在O_Append中,如果写作太大,输出可能会重叠。由于您使用的是缓冲io(这是FILE*
是什么),因此这可能不太可能,但并非不可能。在这一点上,您最好的选择就是抓住这个机会,也相对频繁地到fflush
,以便发送给write
的缓冲区不太大。