2014-01-12 48 views
0

我使用的是C.例如目前正在实施& &功能的外壳,如果我们输入CMD1 & & CMD2,然后CMD2只有当执行CMD1成功退出。我在想:是否在子进程中返回的功能,可以在父进程捕获

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,因为我想知道该命令是否成功退出。但我不确定父进程是否可以从子进程获得返回值,因为它们是两个不同的进程。

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

+0

与你的问题无关,但至少有两个问题'strcmp(args [sizeof(args)],'&')' –

+0

阅读[高级Linux编程](http://advancedlinuxprogramming.com/) –

回答

3

变化:

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 

你设置pidfork() < 0结果,它不设置对孩子的PID。因此,除非fork()中有错误,否则父母和孩子都会设置pid0,所以他们都认为他们是孩子。

关于​​函数的返回值:它将返回父代和子代。在每个过程中,它将返回​​中if的相应分支中的return语句中指定的内容。请注意,它execve()成功,孩子永远不会返回,因为它不再运行这个程序,它运行着被执行的程序。

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

+0

哦,是的,我明白了。谢谢。但实际上我的问题是,是否可以在父进程中捕获子进程中返回的值。也就是说,我是否可以写if(execute(cmd1)!= -1)?谢谢。 –

+1

除了退出状态,您可以使用'waitpid()'获取子进程中没有发生的任何情况。 – Barmar

+0

非常感谢。但在这里我仍然不明白为什么execute函数将在父进程和子进程中都返回?如果我想实现&&功能,我应该只在儿童中运行一个cmd,如果儿童成功退出,我应该在父亲中运行另一个cmd?我现在正在分派两个孩子来做这件事。 –

相关问题