【问题标题】:whether a function returned in the child process can be captured in the parent process子进程返回的函数是否可以在父进程中被捕获
【发布时间】:2014-01-12 04:02:09
【问题描述】:

我目前正在使用 C 在 shell 中实现 && 功能。例如,如果我们输入 cmd1 && cmd2,则只有在 cmd1 成功退出时才会执行 cmd2。我在想:

int main() {
    int i;
    char **args; 

    while(1) {
        printf("yongfeng's shell:~$ ");
        args = get_line();
        if (strcmp(args[0], "exit") == 0) exit(0);     /* if it's built-in command exit, exit the shell */
        if('&&') parse_out_two_commands: cmd1, cmd2;
        if (execute(cmd1) != -1)   /* if cmd1 successfully executed */
            execute(cmd2);       /* then execute the second cmd */
    }
}

int execute(char **args){
    int pid;
    int status;   /* location to store the termination status of the terminated process */
    char **cmd;   /* pure command without special charactors */

    if(pid=fork() < 0){   //fork a child process, if pid<0, fork fails
        perror("Error: forking failed");
        return -1;
    }

    /* child */
    else if(pid==0){             /* child process, in which command is going to be executed */
        cmd = parse_out(args);
        /* codes handleing I/O redirection */

        if(execvp(*cmd, cmd) < 0){   /* execute command */
            perror("execution error");
            return -1;
        }
        return 0;
    }
    /* parent */
    else{         /* parent process is going to wait for child or not, depends on whether there's '&' at the end of the command */
        if(strcmp(args[sizeof(args)],'&') == 0){
            /*  handle signals */
        }
        else if (pid = waitpid(pid, &status, 0) == -1) perror("wait error");
    }
}

所以我使用另一个函数 int execute(char ** args) 来完成实际工作。它的返回类型是 int 因为我想知道命令是否成功退出。但是我不确定父进程是否可以从子进程那里获取返回值,因为它们是两个不同的进程。

或者我应该决定是否在子进程中执行第二个命令,通过派生另一个进程来运行它?非常感谢。

【问题讨论】:

标签: c linux unix fork parent-child


【解决方案1】:

变化:

if(pid=fork() < 0){   //fork a child process, if pid<0, fork fails

到:

if((pid=fork()) < 0){   //fork a child process, if pid<0, fork fails

您将pid 设置为fork() &lt; 0 的结果,而不是将其设置为孩子的PID。因此,除非fork() 中有错误,否则这会将父母和孩子中的pid 设置为0,因此他们都认为自己是孩子。

关于execute()函数的返回值:在父子函数中都会返回。在每个进程中,它将返回execute()if 的相应分支中return 语句中指定的任何内容。注意它execve() 是成功的,孩子永远不会回来,因为它不再运行这个程序,它正在运行被执行的程序。

如果孩子想要向父母发送成功或失败信息,它会使用其退出状态来执行此操作,通过调用exit(0) 表示成功,并调用exit(some-nonzero-value) 表示失败。父级可以使用waitpid 获取退出状态,然后从execute() 返回成功或失败指示。

【讨论】:

  • 哦,是的,我明白了。谢谢你。但实际上我的问题是子进程中返回的值是否可以在父进程中被捕获。也就是说,我是否可以写 if (execute(cmd1) != -1) ?谢谢。
  • 子进程中发生的任何事情对父进程都是不可见的,除了它的退出状态,您可以使用waitpid() 获得。
  • 非常感谢。但是在这里我还是不明白为什么execute函数会在父进程和子进程中都返回?如果我想实现 && 功能,我应该只在子进程中运行一个 cmd,如果子进程成功退出,则在父进程中运行另一个命令?我目前正在派两个孩子来做这件事。
  • 当你 fork 时,父函数和子函数都会继续执行。如果它们都执行return 语句或到达函数的末尾,它们都会返回。子进程在子进程中返回,父进程在父进程中返回。
  • 但是,当您使用execve 时,您将不再运行调用fork 的程序。子进程现在正在运行被命名的程序,并且execute() 永远不会在子进程中返回。父进程必须调用waitpid(),检查退出状态,从execute()返回成功。
猜你喜欢
  • 1970-01-01
  • 2017-01-08
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
  • 2018-04-05
相关资源
最近更新 更多