- 论坛徽章:
- 0
|
整理APUE没搞懂的知识点,遇到system函数对信号的处理,感觉讲的不明白,自己也想不明白。
第一个问题: system函数是运行/bin/sh -c cmdstring来运行我们的命令的,比如是是ed编辑器, 我们的主程序是a.out,其中调用system("/bin/ed") .
shell -> a.out -> /bin/sh -> /bin/ed
a.out -> /bin/sh 另外还有一个父进程存在 设为 a.out
/bin/sh -> /bin/ed 不是应该也有一个shell的父进程存在吗, 为什么书上说 ed进程结束 ,系统会直接向 a.out发送 SIGCHID信号。 而不是向sh父车进程发送信号。
/bin/sh 是作为怎样的进程运行的?
第二个问题:
此外system函数忽略SIGINT 和 SIGQUIT 这样导致 a.out /bin/sh /bin/ed 三个前台进程都会收到信号,
在进入system函数时候先进行了对这两个信号的忽略,这样a.out 进程不会对此信号做出反应。但是在fork()的子进程恢复了对这两个信号的处理,这样这两个信号同样会传递给 /bin/sh 和 /bin/ed 。 ed进程对这两个信号是默认忽略的。 我的linux系统 /bin/sh 连接指向的是 dash ,当我输入 ctrl+\ 时 并没有被忽略,而是造成了 sh进程的结束,导致ed变成了孤儿进程。 但是如果我把 /bin/sh 改成 /bin/bash 则会忽略 SIGQUIT信号。 这是shell版本的问题吗?- if (sigaction(SIGINT, &ignore, &saveintr) < 0)
- return(-1);
- if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
- return(-1);
- sigemptyset(&chldmask); /* now block SIGCHLD */
- sigaddset(&chldmask, SIGCHLD);
- if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
- return(-1);
- if ((pid = fork()) < 0) {
- status = -1; /* probably out of processes */
- } else if (pid == 0) { /* child */
- /* restore previous signal actions & reset signal mask */
- sigaction(SIGINT, &saveintr, NULL);
- sigaction(SIGQUIT, &savequit, NULL);
- sigprocmask(SIG_SETMASK, &savemask, NULL);
- execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); //-> 这是改为 /bin/bash 则 忽略SIGQUIT信号
- _exit(127); /* exec error */
- } else { /* parent */
- while (waitpid(pid, &status, 0) < 0)
- if (errno != EINTR) {
- status = -1; /* error other than EINTR from waitpid() */
- break;
- }
- }
复制代码 第三个问题:
孤儿进程组的进程 忽略 SIGTSTP 信号吗? |
|