【发布时间】:2019-03-19 03:19:53
【问题描述】:
来自 APUE 的 Unix system 函数的实现:
图 8.22
system函数,没有信号处理
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
int
system(const char *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */
if ((pid = fork()) < 0) {
status = -1; /* probably out of processes */
} else if (pid == 0) { /* child */
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); /* execl error */
} else { /* parent */
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR) {
status = -1; /* error other than EINTR from waitpid() */
break;
}
}
// if(waitpid(pid, &status, 0) < 0){
// if(errno != EINTR){
// status = -1;
// }
// }
}
return(status);
}
为什么它对waitpid 使用while 循环而不是我在cmets 中添加的if 语句?我试过if,到目前为止没有出错。
【问题讨论】:
-
事实上所有阻塞系统调用可以返回
EINTR,你需要重试。 -
@AnttiHaapala 嗯,如
man waitpid中所述,如果一个进程被信号停止或恢复,这种状态变化将被waitpid捕获,但是它们被认为是waitpid的成功返回,这2种的信号与我们所说的EINTP中断信号不一样,是吗?对吗? -
这些是等待进程的信号,这里我们讨论的是运行
waitpid的进程接收到的信号。 -
再一次,正如重复中所解释的那样,
EINTR此处的处理并非特定于waitpid,而是 any 阻塞系统调用可能会失败,您需要准备重试。 -
不,如果孩子只是停止(未终止)或恢复,它根本不会返回,因为标志(第三个参数)设置为 0