假设我们有一个代码做这样的事情:
int pipes[2];
pipe(pipes);
pid_t p = fork();
if(0 == p)
{
dup2(pipes[1], STDOUT_FILENO);
execv("/path/to/my/program", NULL);
...
}
else
{
//... parent process stuff
}
正如你所看到的,它正在创建一个管道,分叉并使用管道来读取子输出(我不能在这里使用popen
,因为我还需要子进程的PID用于其他目的) 。
问题是,如果在上面的代码中execv
失败了会发生什么?我应该调用exit()还是abort()?据我所知,这些函数关闭了打开的文件描述符。由于fork
- ed进程继承了父进程的文件描述符,这是否意味着父进程使用的文件描述符将变得无法使用?
UPD
我想强调的是,问题不在于exec()加载的可执行文件是否失败,而是exec本身,例如:如果第一个参数引用的文件未找到或不可执行。
答案 0 :(得分:3)
您应该使用exit(int)
,因为父进程可以使用waitpid()
读取参数的(低字节)。这使您可以在父进程中适当地处理错误。根据您的计划的不同,您可能需要使用_exit
而不是exit
。区别在于_exit
不会运行用atexit
注册的函数,也不会刷新stdio流。
答案 1 :(得分:0)
大约有十几个原因导致execv()
失败,您可能希望以不同的方式处理每个原因。
孩子失败不会影响父母的文件描述符。它们实际上是参考计数。
答案 2 :(得分:0)
你应该致电_exit()
。它完成了exit()
所做的一切,但它避免了调用任何已注册的atexit()
函数。调用_exit()
表示父母将能够获得失败孩子的退出状态,并采取任何必要步骤。