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