psi*_*tte 5 c fork execv waitpid
主进程如何知道子进程执行文件失败(例如没有这样的文件或目录)?例如,在下面的代码中,我们怎样才能让 run() 返回 0 以外的值呢?谢谢!
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
enum ErrorType { noError, immediateFailure, returnFailure, forkFailure };
using namespace std;
int run(void)
{
int error = noError;
//char proc[] = "/bin/uname";
char proc[] = "/usr/bin/Idontexist";
char *const params[] = {proc, NULL};
pid_t pid = fork();
printf("pid = %d\n",pid);
if (pid == 0)
{
if ( execv(proc,params)==-1 )
{
error = immediateFailure;
}
printf("child: error = %d\n",error);
}
else if (pid > 0)
{
/* This is the parent process
* incase you want to do something
* like wait for the child process to finish
*/
int waitError;
waitpid(pid, &waitError, 0);
if ( waitError )
error = returnFailure;
printf("parent: error = %d, waitError = %d\n",error,waitError);
}
else
{
error = forkFailure;
}
return error;
}
int main(void)
{
printf("run() = %d\n",run());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
pid = 4286
pid = 0
child: error = 1
run() = 1
parent: error = 0, waitError = 0
run() = 0
Run Code Online (Sandbox Code Playgroud)
main您需要从或 中返回错误代码exit()以及值。现在,您在所有情况下都是returnfrom 0,main这将是父级从 收到的子级的退出代码waitpid。
_exit(error)最好的解决方法是在子进程中添加:
printf("child: error = %d\n",error);
_exit(error);
Run Code Online (Sandbox Code Playgroud)
无论如何,请使用整数常量而不是随机枚举常量 enum。1 和 2 是许多 unix 命令的常见返回值,其中 1 表示命令不成功(例如grep没有找到任何匹配项),2+ 表示命令确实失败(参数错误等)。
bash,zsh以及其他 shell 用作127退出代码来指示命令未找到/无法运行;因此建议:
#define COMMAND_NOT_RUNNABLE 127
/* ... */
execv(proc, params); // exec never returns if successful.
perror(proc);
_exit(COMMAND_NOT_RUNNABLE);
Run Code Online (Sandbox Code Playgroud)
在子进程中使用的原因_exit是它不会刷新 stdio 缓冲区(这也存在于父进程中)并且它不会运行钩子atexit。(感谢安德鲁·亨利)