1

假设我们有一个代码做这样的事情:

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 本身,例如,如果第一个参数引用的文件未找到或不可执行。

4

3 回答 3

3

您应该使用exit(int)参数的(低字节),因为父进程可以使用waitpid(). 这使您可以在父进程中适当地处理错误。根据您的程序的用途,您可能想要使用_exit而不是exit. 不同之处在于它_exit不会运行注册的函数,atexit也不会刷新 stdio 流。

于 2012-06-26T21:20:14.123 回答
0

大约有十几个原因execv()可能会失败,您可能希望以不同的方式处理每一个。

子失败不会影响父文件描述符。实际上,它们是参考计数的。

于 2012-06-26T21:11:28.247 回答
0

You should call _exit(). It does everything exit() does, but it avoids invoking any registered atexit() functions. Calling _exit() means that the parent will be able to get your failed child's exit status, and take any necessary steps.

于 2012-06-26T21:22:22.153 回答