【问题标题】:How to change signal handler in child-process?如何更改子进程中的信号处理程序?
【发布时间】:2019-03-30 10:29:39
【问题描述】:

我正在编写一个带有作业控制的 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(...);

但子进程忽略信号

【问题讨论】:

    标签: c signals child-process job-control


    【解决方案1】:

    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);
    

    【讨论】:

    • 是的,就是这个!非常感谢!
    猜你喜欢
    • 2014-12-09
    • 2016-03-07
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多