【问题标题】:segmentation fault signal handler sigint分段错误信号处理程序信号
【发布时间】:2016-03-26 23:32:30
【问题描述】:

我正在尝试捕捉 SIGINT (CTRL + C)。 我希望当用户键入 CTRL + C 时,它会杀死子进程,但父进程将正常继续。 当我的程序中有子进程时它工作正常,但是当我没有子进程时,我得到“分段错误”。

我已经这样做了:

void sig_handler(int signo);
//========================================
int main()
{
    // CTRL + C => SIGINT handler
    struct sigaction act;
    act.sa_handler = sig_handler;
    sigfillset(&act.sa_mask);
    act.sa_flags = 0;

    // Catch the signal
    sigaction(SIGINT, &act, NULL);
...
// done some checks and then fork a child.
} 

// SIGINT handler
void sig_handler(int signo)
{
 // dont know what to write here
}

【问题讨论】:

  • 在 fork 你的子进程之前获取当前进程 ID,然后 fork 你的子进程并获取它的进程 ID 然后在处理信号时检查 ctrl c 是否用于父进程 ID 然后实现你的根据它的逻辑。
  • 在哪一行代码中出现分段错误?

标签: c signals fork


【解决方案1】:

我相信只要使用 sigset() 就可以实现你的目标。

我会引用 sigset 手册页中的一些信息。

sigset() 函数修改信号配置。信号参数 指定信号,可以是除 SIGKILL 和 SIGSTOP 之外的任何信号。 disp 参数指定信号的处置,可能是 SIG_DFL、SIG_IGN 或信号处理程序的地址。如果 sigset() 是 使用过,disp 是信号处理程序的地址,系统将 sig 添加到 执行信号前调用进程的信号掩码 处理程序;当信号处理程序返回时,系统恢复信号 调用进程的掩码到它在交付之前的状态 信号。另外,如果使用sigset(),并且disp等于SIG_HOLD, sig 被添加到调用进程的信号掩码和 sig 的 处置不变。如果使用了 sigset(),而没有使用 disp 等于 SIG_HOLD,从调用的信号掩码中删除 sig 过程。

参考此链接:sighold, sigignore, sigpause, sigrelse, sigset — legacy interface for signal management

您可以建立一个处理函数,当您获得 SIGINT 时将调用该函数。

void handler(int signo){
    // Here you can kill the child, if it exists
}

int main(int argc, char *argv[])
{
     ...
     sigset(SIGINT, handler);
     ...
}

希望对您有所帮助,如果您需要更多帮助,请在 cmets 中提及。

【讨论】:

  • 如果答案解决了您的问题,请点赞。 --谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 2013-06-19
  • 2013-06-03
  • 1970-01-01
  • 2015-05-01
相关资源
最近更新 更多