所以我有一个调用 execvp() 的程序,如下所示
void ext_com(char* buffer){
char **command;
pid_t child_pid;
command = get_input(buffer);
child_pid = fork();
if(child_pid<0){
perror("failed");
exit(1);
}
if (!child_pid) {
/* Never returns if the call is successful */
int ret= execvp(command[0], command);//call ls
if(ret == -1){
printf("bad command\n");
last_exit = ret;
exit(ret);
}
} else {
int stat_loc;
run_pid = child_pid;
waitpid(child_pid, &stat_loc, WUNTRACED) &255;
last_exit=stat_loc;
}
free(command);
}
其中last_exit是一个全局int,当我正确运行命令时,last_exit状态不是0,当我运行错误命令时,它也不是-1,当我运行一些不存在的标志(例如ls 444)时,它也不是1。 它有时确实返回 1 到 255 之间的数字,但是这种行为是否错误(除了正确调用 execvp() 时返回非零之外),以及如何修复它。
谢谢你
fork()
其中last_exit是一个全局int,
当您
fork()
一个子进程时,子进程会获得其父进程内存的副本。除非您利用共享内存机制,否则子级无法通过变量与父级进行通信,无论其范围或链接如何。
特别是在这个代码片段中...
last_exit = ret; exit(ret);
...对
last_exit
的分配是无用的,因为它影响的(唯一)进程随后立即终止。
execvp()
当我运行一些不存在的标志(例如 ls 444)时,它也不是 1。
程序的参数是否有效是程序自己决定的事情。除非成功启动,否则还没有达到进行此类评估的目的。
execvp()
的返回值与其启动的程序的退出状态或任何其他行为无关。它不会等待该程序完成,因此该信息甚至可供它使用。如果execvp()
能够启动指定的程序根本,则不会返回,并且仅当无法启动时才会失败(返回-1)。请注意,这意味着您永远不必测试其返回值——如果该函数完全返回,那么您无需检查返回值是否为 -1 即可知道。失败通常是由于找不到指定的程序、无法访问执行或不具有可识别的可执行格式而导致的。
如果您想了解该程序的退出状态,则父进程(执行
fork()
调用的子进程)必须 execvp()
或 wait()
,并使用该信息由该函数提供。关于 waitpid()
exit()
虽然 waitpid()
接受
exit()
参数,但 int
函数系列(或 shell)中可用的退出状态仅传达 8 位退出状态信息。特别是,wait()
的参数并未通过exit()
全部传达给父级。这样可用的退出状态(如果程序正常终止)是 0 到 255 之间的数字。waitpid()
系列函数提供的状态代码传达多种信息,包括
进程是否正常终止,如果是,以及8位退出状态wait
wait
来验证它是否正常终止。假设确实如此,
WIFEXITED(stat_loc)
将为您提供退出状态,该状态同样只有 8 个有效位。如果子进程通过调用 WEXITSTATUS(stat_loc)
终止,那么您应该期望通过 exit(-1)
报告的状态为 255。