10_26 當調用system函數時子進程與父進程對信號的處理,尤其是SIGCHLD

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章