posix.1 标准规定,当在执行system函数时,应该阻止对父进程递送SIGCHLD信号。
因为如果不阻止,当system创建的子进程结束时,system调用者可能错误的认为,它自己的一个子进程结束了,从而调用一种wait函数以获得子进程退出状态,进而阻止了system函数里获得子进程的终止状态,并将其返回。
还因为system函数如果调用了交互式的应用,如本例的ed,其实父进程已经丧失了控制,应当等待该进程结束。
首先看直接调用标准的system函数时的运行结果。成功阻塞了对父进程信号(中断和退出)的传递。
源代码:
vim 10_26.c
#include "apue.h"
static void sig_int(int signo)
{
printf("Caught SIGINT\n");
}
static void sig_child(int signo)
{
printf("Caught SIGCHILD\n");
}
int main(void)
{
if(signal(SIGINT,sig_int) == SIG_ERR)
err_sys("signal SIGINT error");
if (signal(SIGCHLD,sig_child) == SIG_ERR)
err_sys("signal SIGCHLD error");
if (system("/bin/ed") < 0)
err_sys("system() error");
exit(0);
}
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
"10_26.c" [New] 25L, 391C written
<bldc:/home/tingbinz/apue.3e/SBSCODE/10>R*_*G:gcc -Wall -ggdb3 error.c 10_23.c -o jump_out_while
error.c: In function `err_doit':
error.c:121: warning: implicit declaration of function `vsnprintf'
error.c:123: warning: implicit declaration of function `snprintf'
<bldc:/home/tingbinz/apue.3e/SBSCODE/10>R*_*G:gcc -Wall -ggdb3 error.c 10_26.c -o CHILD_Catch_signal
error.c: In function `err_doit':
error.c:121: warning: implicit declaration of function `vsnprintf'
error.c:123: warning: implicit declaration of function `snprintf'
运行结果。
<bldc:/home/tingbinz/apue.3e/SBSCODE/10>R*_*G:./CHILD_Catch_signal
a
hello,world
.
1,$p
hello,world
w temp.foo
12
^C
?
q
<bldc:/home/tingbinz/apue.3e/SBSCODE/10>R*_*G:
<bldc:/home/tingbinz/apue.3e/SBSCODE/10>R*_*G:
调用自己写的system函数,未阻塞信号,所以中断和退出信号都发送给了父进程和子进程。
自己system函数的源代码。
vim 8_22.c
#include "apue.h"
#include <errno.h>
#include <unistd.h>
int system(const char *cmdstring)
{
pid_t pid;
int status;
if ((pid = fork()) < 0){
status = -1;
}else if (pid == 0){
execl("/bin/sh","sh","-c",cmdstring, (char*) 0);
err_sys("execl:%s error",cmdstring);
_exit(127);
}else{
while (waitpid(pid,&status,0) < 0){
if (errno != EINTR){
status = -1;
break;
}
}
}
return (status);
}
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
编译及运行结果:
:gcc -Wall -ggdb3 8_22.c error.c 10_26.c -o CHILD_Catch_signal
8_22.c: In function `system':
8_22.c:17: warning: implicit declaration of function `waitpid'
error.c: In function `err_doit':
error.c:121: warning: implicit declaration of function `vsnprintf'
error.c:123: warning: implicit declaration of function `snprintf'
./CHILD_Catch_signal
a
hello,world
.
1,$p
hello,world
w temp.foo
12
^C
?
Caught SIGINT
q
Caught SIGCHILD