system函数

1、system函数学习

定义函数 

// param: cmd命令字符串
// return: -1:出现错误,  0:调用成功但是没有出现子进程, 127:调用/bin/sh时失败,  >0:成功//退出的子进程的id
int system(const char * cmdstring)
{ 
  pid_t pid; 
  int status; 
  if(cmdstring == NULL)
  { 
    return (1); 
  } 
  if((pid = fork())<0)
  { 
    status = -1; 
  } 
  else if(pid = 0)
  {
     execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
         _exit(127); //子进程正常执行则不会执行此语句
  }
  else //父进程
  { 
    while(waitpid(pid, &status, 0) < 0)
    {
       if(errno != EINTR)
      {
         status = -1; //如果waitpid被信号中断,则返回-1 
         break; 
      } 
    }
   } 
  return status; 
}        

   

因此system()实际是执行三个步骤:

1、fork一个子进程

2、子进程中调用exec函数去执行cmdstring

3、在父进程中调用waitpid去等待子进程结束

 system函数会阻塞等待子进程的结束

判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立:

             1-1 != status

             2WIFEXITED(status) != 0 // 子进程正常退出

             3 WEXITSTATUS(status)是否为子进程返回值

 

如果在system()调用前,SIGCHID信号被设置为 SIG_IGN, waitpid()函数有可能因为捕捉不到子进程状态信息而阻塞,并且ECHILD错误,可以用如下方法使用

 

  sighandler_t old_handler; 
  old_handler = signal(SIGCHLD, SIG_DFL); // SIG_DFL 恢复默认行为, SIG_IGN 屏蔽该信号
  ret = system(cmdstring); 
  signal(SIGCHLD, old_handler);     

 

 

 

posted @ 2019-11-26 23:22  ho966  阅读(614)  评论(0编辑  收藏  举报