我正在通过Richard Stevens“UNIX环境中的高级编程”,我找到了这个主题。
* 8.13。系统功能
*****因为系统是通过调用fork,exec和waitpid实现的,所以有三种类型的返回值。**
1。如果fork失败或者waitpid返回EINTR以外的错误,则系统返回-1并设置errno以指示错误。
2。如果exec失败,暗示shell无法执行,则返回值就好像shell已执行exit(127)。
** 3。否则,所有三个函数 - fork,exec和waitpid-success,以及来自system的返回值是shell的终止状态,格式为waitpid。******
根据我的理解,我们 fork() cmdstring name 和 exec()的流程使其与父流程分开。
但无法弄清 waitpid()函数如何成为 system()函数调用的一部分?
以下链接ambiguous constructor call while object creation未向我提供正确答案。
答案 0 :(得分:15)
关闭fork()
后,您的原始流程会立即继续,即fork()
立即返回。此时,新进程仍在运行。由于system()
应该是同步的,即只有在执行的程序完成后才能返回,原始程序现在需要在新进程的PID上调用waitpid()
来等待终止。
在图片中:
[main process]
.
.
.
fork() [new process]
A
/ \
| \
| \___ exec()
waitpid() .
z .
z . (running)
z .
z Done!
z |
+----<----<---+
|
V
(continue)
答案 1 :(得分:2)
在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
可以提供其他值,以及需要检查的各种其他事项。
答案 2 :(得分:1)
从手册页:
system()通过调用/ bin / sh -c命令执行命令中指定的命令,并在命令完成后返回 。在执行命令期间,SIGCHLD将被阻止,SIGINT和SIGQUIT将被忽略。
system()可能使用waitpid()
等待shell命令完成。