多进程编程之system()函数

1、system函数:  

  使用函数system,在程序中执行一个shell命令字符串很方便。它是一个和操作系统紧密相关的函数,用户可以使用它在自己的程序中调用系统提供的各种命令,执行系统的命令行,其实也是调用程序创建一个进程来实现的。实际上,system函数的实现正是通过调用fork、exec、waitpid函数来完成的。system函数原型:

 1 #include <stdlib.h>
 2 
 3 int system(const char* cmdstring);
 4 
 5 /*源码,该源码没有对信号进行处理*/
 6 #include <sys/types.h>
 7 #include <sys/wait.h>
 8 #include <errno.h>
 9 #include <unistd.h>
10 int system(const char * cmdstring)
11 {
12     pid_t pid;
13     int status;
14 
15     if(cmdstring == NULL){      
16          return (1);
17     }
18 
19     if((pid = fork())<0){
20             status = -1;
21     }
22     else if(pid = 0){
23         execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
24         _exit(127); //子进程正常执行则不会执行此语句
25         }
26     else{
27            while(waitpid(pid, &status, 0) < 0){
28                 if(errno != EINTER){
29                     status = -1;
30                     break;
31                 }
32             }
33         }
34         return status;
35 }

2、system函数的返回值:

  由于system是通过fork、exec、waitpid函数实现的,则system对返回值的处理分为三个阶段:

  阶段1 fork失败,返回-1;

  阶段2 调用/bin/sh拉起shell脚本,只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。
    (比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。
    即使shell脚本不存在或没有执行权限,也都算正常执行结束。
    如果shell脚本执行过程中被强制kill掉等情况则算异常结束。)    

    如何判断阶段2中shell脚本是否正常结束?如何判断阶段2中,shell脚本是否正常执行结束呢?系统提供了宏:WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。

  阶段3 如果shell脚本正常执行结束,将shell返回值填到status的低8~15比特位中;

    如何取得阶段3中的shell返回值?你可以直接通过右移8bit来实现,但安全的做法是使用系统提供的宏:WEXITSTATUS(status)。

总结:

  判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立
  (1)-1 != status 创建子进程成功
  (2)WIFEXITED(status)为真  子进程正常退出
  (3)0 == WEXITSTATUS(status)  shell命令执行成功

例:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <sys/wait.h>
 4 int main(int argc, char **argv)
 5 {
 6         int status = 0;
 7         status = system("exit 44");
 8         if (status == -1) {
 9                 printf("fork failed
");
10                 return 0;
11         }
12         if (WIFEXITED(status)) {
13                 printf("normal exit status = %d
",WEXITSTATUS(status));
14         }
15         return 0;
16 }
原文地址:https://www.cnblogs.com/funblogs/p/7571321.html