如果exec()失败怎么办?
让我们假设我们有一个这样做的代码:如果exec()失败怎么办?,c,linux,unix,ipc,fork,C,Linux,Unix,Ipc,Fork,让我们假设我们有一个这样做的代码: 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,因为我还需要子进程的
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本身,例如,如果第一个参数引用的文件找不到或不可执行。大约有十几个原因导致execv()失败,您可能希望以不同的方式处理每一个原因
失败的子级不会影响父级的文件描述符。实际上,它们是引用计数的。您应该使用
exit(int)
,因为父进程可以使用waitpid()
读取参数的(低字节)。这允许您在父进程中适当地处理错误。根据您的程序,您可能希望使用\u exit
而不是exit
。不同之处在于\u exit
不会运行使用atexit注册的函数,也不会刷新stdio流。您应该调用\u exit()
。它完成exit()
所做的一切,但它避免调用任何已注册的atexit()
函数。调用\u exit()
意味着家长将能够获取失败孩子的退出状态,并采取任何必要的步骤。如果您不希望出现混乱的控制流,我建议exit()在失败的exec上使用已知的退出代码。嘿,伙计们,但是如果exit()呢
也会失败?我不认为这应该是一个问题-在最坏的情况下,atexit
函数中发生的任何有趣的事情都会导致异常终止,否则我们无法控制它(退出永远不会返回)。