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

时间:2019-01-16 22:39:12

标签: 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 (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;
    }

}

它没有多大意义(不要介意tokens2[]数组,它已经正确声明并且可以正常工作),因为它是抽象形式的,以便可以听见且易于理解了解。问题是:函数foo的输出是什么?这是到目前为止我得到的:

  

1)如果execvp成功,则不返回任何值。如果失败,它将返回-1(我认为此返回值不必与我的foo函数无关)。

     

2)exit(1)杀死子进程并将控制流返回给父进程。

据我了解,如果execvp成功,foo应该返回-1(根据变量fail),如果失败,它应该返回0 ,但这不是我的printf在主要功能显示中检查的内容。实际上,结果总是与我期望的相反。

PS:我发现了一些关于execvp的错误处理方法,这些错误处理方法使用了很好的 shelf-pipe 技巧,但对我来说太吵了。我想要一种更简单的方法来处理错误。

2 个答案:

答案 0 :(得分:1)

  

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

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

  
1)If execvp succeeds, it does not return any value.
  

如果execvp()成功,则完全不返回

  
    

如果失败,则返回-1(我认为此返回值不必执行任何操作     和我的foo函数)。

  

是的。但是,只有您的子进程执行execvp(),并且在返回时,该进程最终会调用exit()

  
2)exit(1) kills the child process and returns the control flow to the parent.
  

那会在从foo()返回之前终止该进程,因此在子进程foo()中永远不会返回,无论execvp是否成功。控件不会返回父级。派生进程与调用函数根本不同。父母可以通过进行的waitpid()调用来了解孩子的退出代码。

在父级中,如果fork()失败,则该过程也会调用exit(),因此不会从foo()返回。另一方面,假设fork()成功,则父级等待直到子级终止。子进程是一个单独的进程,具有所有变量的自己的副本,因此,对其fail副本所做的任何操作均不会对父进程产生影响。也就是说,派生子进程也不同于在同一进程中启动线程。

由于父级本身不会修改fail,因此如果达到,父级仍具有其初始值10。

    if (fail == 1){

10!= 1,所以如果foo()返回,则返回0。

答案 1 :(得分:0)

execvp 用您exec处理的过程覆盖整个过程

如果execvp成功,则fail变量将不再存在于子级中。 foo函数在子级中不再存在。子级中不再存在称为foo的函数。如果execvp成功,则孩子现在正在运行不同程序的 main函数。

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