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


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值