waitpid()函数是如何在linux中的system()函数中实现的

how waitpid() function is implemented in system() function in linux

本文关键字:函数 system 中的 实现 waitpid linux      更新时间:2023-10-16

我正在学习Richard Stevens的"UNIX环境中的高级编程",发现了这个主题。

*8.13.系统功能

*****因为系统是通过调用fork、exec和waitpid来实现的,所以有三种类型的返回值。**

1.如果fork失败或waitpid返回EINTR以外的错误,系统将返回–1,并设置errno以指示错误

2.如果exec失败,意味着shell无法执行,则返回值就像shell执行了exit(127)

**3.否则,fork、exec和waitpid这三个函数都成功,系统返回的值是shell的终止状态,格式为waitpid。******

据我所知,我们fork()通过cmdstring名称exec()

但是无法弄清楚waitpid()函数是如何成为system()函数调用的一部分的?

以下链接在创建对象时调用了不明确的构造函数,但没有为我提供正确的答案。

关闭fork()后,原始进程立即继续,即fork()立即返回。此时,新流程仍在运行。由于system()应该是同步的,即必须在执行的程序结束后才返回,因此原始程序现在需要在新进程的PID上调用waitpid()来等待其终止。

图片中:

   [main process]
         .
         .
         .
       fork()     [new process]
         A
        / 
       |   
       |    ___  exec()
  waitpid()         .
      z             .
      z             . (running)
      z             .
      z           Done!
      z             |
      +----<----<---+
      |
      V
  (continue)

在Unix环境中,system()调用看起来像这样:

int system(const char *cmd)
{
   int pid = fork();
   if(!pid)  // We are in the child process. 
   {
       // Ok, so it's more complicated than this, it makes a new string with a
       // shell in it, etc. 
       exec(cmd);
       exit(127);  // exec failed, return 127. [exec doesn't return unless it failed!]
   }
   else
   {
       if (pid < 0)
       {
            return -1;   // Failed to fork!
       }
       int status;
       if (waitpid(pid, &status, 0) > 0)
       {
           return status;
       }
   }
   return -1;
}

请注意,这就是system的作用——它有点复杂,因为waitpid可以给出其他值,以及所有其他需要检查的东西。

来自手册页:

system()通过调用/bin/sh-c命令执行命令中指定的命令,并在命令完成后返回。在执行命令期间,SIGCHLD将被阻止,SIGINT和SIGQUIT将被忽略。

system()可能使用waitpid()来等待shell命令完成。