execvp()-exit()返回函数中的值

execvp()-exit()返回函数中的值,c,error-handling,exit,execvp,C,Error Handling,Exit,Execvp,我最近一直在与以下概念作斗争,但我仍然无法理解它。我有这段代码 int foo(int f){ int fail = 10; //some random initialization value int status; pid_t child_pid; child_pid = fork(); if(child_pid == 0) { /* This is done by the child process. */ if

我最近一直在与以下概念作斗争,但我仍然无法理解它。我有这段代码

int foo(int f){
    int fail = 10;  //some random initialization value
    int status;
    pid_t child_pid;
    child_pid = fork();

    if(child_pid == 0) {
        /* This is done by the child process. */

        if (execvp(tokens2[0], tokens2)<0){
            fail =1;
            perror(tokens2[0]); 
            exit(1);
        }
    }else if(child_pid<0){
        perror("Fork failed");
        exit(1);
    } else {
        waitpid(child_pid, &status, WUNTRACED);
    }

    //handle execvp error return value
    if (fail == 1){
        return -1;
    }else{
        return 0;
    }
    
}
intfoo(intf){
int fail=10;//一些随机初始化值
智力状态;
pid_t child_pid;
child_pid=fork();
如果(子项pid==0){
/*这是由子进程完成的*/
如果(execvp(tokens2[0],tokens2)
execvp
用您正在执行的流程覆盖整个流程

如果
execvp
成功,则子级中不再存在
fail
变量。子级中不再存在
foo
函数。调用
foo
的函数不再存在于子级中。如果
execvp
成功,则子级现在正在运行另一个程序的
main
函数

最终,该程序将退出,然后子进程将退出。它永远不会返回到您的程序。(这就是为什么您需要创建一个单独的进程来调用
execvp
in-如果您使用原始进程,您将永远无法返回它)

问题是:函数foo的输出是什么

您似乎在问
foo()
的返回值是多少。“输出”通常指写入终端或外部文件的数据。但问题仍然是:在哪个进程中?假设
fork()
成功,则有两个几乎相同的进程,都在执行
foo()

如果
execvp()
成功,则根本不会返回

如果失败,它将返回-1(我认为这个返回值不必做任何事情) 使用我的foo函数)

是的。但是,只有您的子进程执行
execvp()
,如果返回,该进程将调用
exit()

它在进程从
foo()
返回之前终止进程,因此在子进程
foo()中
永远不会返回,无论
execvp
成功与否。控件不会返回到父级。派生进程与调用函数完全不同。父级可以通过它所做的
waitpid()
调用了解子级的退出代码

在父级中,如果
fork()
失败,则该进程也会调用
exit()
,因此不会从
foo()
返回
成功,另一方面,父进程等待子进程终止。子进程是一个单独的进程,拥有所有变量的副本,因此它对其
失败的副本所做的任何操作都不会对父进程产生影响。也就是说,分支子进程与在同一进程中启动线程不同

由于父级本身不修改
fail
,因此如果达到


10!=1,因此如果
foo()
确实返回,那么它将返回0。

我刚刚发现,当调用
exit(1)
时,子进程将被销毁,其中发生的变量更改也将被销毁。这可能是答案吗?您真的不希望
waitpid()中的
WUNTRACED
选项
。无论如何,不在显示的代码中。作业控制外壳程序可能会使用它,但外壳程序这样做也会注意返回值和状态信息。使用
0
作为
waitpid()的最后一个参数
除非您想查看是否有终止的进程,否则在这种情况下,
WNOHANG
变得相关且有用。
fork()
foo
函数中被调用。我认为
foo
函数“不再存在”当child退出时,那么您就错了,@johngonidelis。如果child的
execvp
调用成功,那么该过程中确实不再存在
foo
,除非替换原始程序的程序有自己的
foo
。即使在这种情况下,执行仍将在
main
中开始,而不是在
foo
中开始。@johngonidelis它不存在于子对象中。它仍然存在于主对象中,因为它们是分开的。非常感谢。在这种情况下,-1会返回吗?正如我所说,@johngonidelis,“如果
foo()
确实返回,那么它会返回0。”在任何情况下,给定的
foo
都不会返回-1。如果
fail
变量被
status
变量替换怎么办?我是否能够检测到
execvp()
succeed或no?不是直接的,@johngonidelis,no。但是如果孩子正常退出——无论其
execvp
成功与否,
waitpid
设置的
状态
编码其退出状态,以及其他内容。您可以在
execlp
失败案例中选择一个存在状态,该状态将d您试图执行的程序绝不会发出,这样就可以区分这两种情况。有关检查状态的详细信息,请参见。
1)If execvp succeeds, it does not return any value.
2)exit(1) kills the child process and returns the control flow to the parent.
    if (fail == 1){