如何更改子进程中的信号处理程序?
How to change signal handler in child-process?
我正在写一个 shell 与作业控制。主进程应该忽略停止信号并处理 SIGCHLD。 fork() 之后的子进程应将信号设置为 SIG_DFL。问题是我的子进程也忽略了信号。
在我的程序开始时,我将 shell 设置为前景并初始化信号
...
tcsetpgrp(shell_terminal, shell_pgid);
set_signals();
void chld_handler(int signum)
{
if (signum == SIGCHLD)
check_and_wait();
return ;
}
void set_signals() {
sigset_t set;
struct sigaction act;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
ft_memset(&act, 0, sizeof(act));
sigfillset(&act.sa_mask);
act.sa_handler = SIG_IGN;
sigaction(SIGINT, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigaction(SIGTTIN, &act, NULL);
sigaction(SIGTTOU, &act, NULL);
act.sa_handler = chld_handler;
sigaction(SIGCHLD, &act, NULL);
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
return;
}
子进程中的 fork() 之后:
/* set to foreground */
pid = getpid();
if (!job->pgid)
job->pgid = pid;
setpgid(pid, job->pgid);
tcsetpgrp(shell_terminal, job->pgid);
/* set signals */
sigset_t set;
struct sigaction act;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
memset(&act, 0, sizeof(act));
sigfillset(&act.sa_mask);
act.sa_handler = SIG_DFL;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
execve(...);
但是子进程忽略了信号
sigaction()
不通过引用存储 sigaction 对象。
将 act.sa_handler
更改为 act.sa_handler = SIG_DFL
后,您需要重复那些 sigaction()
调用。
sigaction(SIGINT, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigaction(SIGTTIN, &act, NULL);
sigaction(SIGTTOU, &act, NULL);
我正在写一个 shell 与作业控制。主进程应该忽略停止信号并处理 SIGCHLD。 fork() 之后的子进程应将信号设置为 SIG_DFL。问题是我的子进程也忽略了信号。
在我的程序开始时,我将 shell 设置为前景并初始化信号
...
tcsetpgrp(shell_terminal, shell_pgid);
set_signals();
void chld_handler(int signum)
{
if (signum == SIGCHLD)
check_and_wait();
return ;
}
void set_signals() {
sigset_t set;
struct sigaction act;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
ft_memset(&act, 0, sizeof(act));
sigfillset(&act.sa_mask);
act.sa_handler = SIG_IGN;
sigaction(SIGINT, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigaction(SIGTTIN, &act, NULL);
sigaction(SIGTTOU, &act, NULL);
act.sa_handler = chld_handler;
sigaction(SIGCHLD, &act, NULL);
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
return;
}
子进程中的 fork() 之后:
/* set to foreground */
pid = getpid();
if (!job->pgid)
job->pgid = pid;
setpgid(pid, job->pgid);
tcsetpgrp(shell_terminal, job->pgid);
/* set signals */
sigset_t set;
struct sigaction act;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
memset(&act, 0, sizeof(act));
sigfillset(&act.sa_mask);
act.sa_handler = SIG_DFL;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
execve(...);
但是子进程忽略了信号
sigaction()
不通过引用存储 sigaction 对象。
将 act.sa_handler
更改为 act.sa_handler = SIG_DFL
后,您需要重复那些 sigaction()
调用。
sigaction(SIGINT, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigaction(SIGTTIN, &act, NULL);
sigaction(SIGTTOU, &act, NULL);