c - 为什么信号处理程序不处理信号
问题描述
我正在尝试制作一个模拟命令 nohup 的程序。程序的第一个参数是要执行的命令的名称。当终端关闭时,我的程序执行的程序一定不能得到通知,它将不得不忽略 SIGHUP。如果我使用以下命令测试我的程序:
./mynohup sleep 120 &
然后我尝试从另一个终端发送一个 SIGHUP,当它应该免疫它时,睡眠终止。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include "utils.h"
#define NOHUP_OUT_FILE "nohup.out"
static void handle_signal(int signum)
{
if(signum == SIGHUP)
{
printf("This is ignored\n");
}
else
{
printf("Not ignored\n");
}
fflush(stdout);
}
/* configure handlers */
static void set_signals(void)
{
struct sigaction sa;
int rc;
/* TODO - ignore SIGHUP */
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handle_signal;
rc = sigaction(SIGHUP, &sa, NULL);
DIE(rc == -1, "sigaction");
}
/* execute a new program */
static void exec_func(int argc, char **argv)
{
int rc;
int i;
char **exec_args;
int fd;
set_signals(); /* ignore SIGHUP */
if(isatty(STDOUT_FILENO))
{
fd = open(NOHUP_OUT_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
DIE(fd < 0, "open");
dup2(fd, STDOUT_FILENO);
close(fd);
}
/* exec a new process */
exec_args = malloc(argc * sizeof(*exec_args));
DIE(exec_args == NULL, "malloc");
for (i = 0; i < argc-1; i++)
exec_args[i] = argv[i+1];
exec_args[argc-1] = NULL;
execvp(exec_args[0], exec_args);
DIE(1, "execvp");
}
int main(int argc, char **argv)
{
if (argc <= 1) {
fprintf(stderr, "Usage: %s command_and_arguments\n", argv[0]);
exit(EXIT_FAILURE);
}
exec_func(argc, argv);
return 0;
}
我试图跳过创建一个新进程并且信号处理程序工作得很好。如果信号处理程序采用以下形式,则程序可以工作
static void set_signals(void)
{
struct sigaction sa;
int rc;
/* ignore SIGHUP */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
rc = sigaction(SIGHUP, &sa, NULL);
DIE(rc == -1, "sigaction");
}
我不明白为什么当我创建信号处理程序的第一个版本时,程序不起作用,而第二个版本却起作用。
提前致谢!
解决方案
所有 exec 函数都将捕获的信号的处置重置为其默认处置。
当您执行时,您的进程映像被破坏并被新程序的进程映像替换。在其中,指向handle_function
您传递给 sigaction 的指针不再具有意义,或者至少不再具有旧意义。操作系统可以对已处理的信号做的唯一明智的事情execve
是重置它们。
的含义SIG_IGN
是通用的并且独立于当前程序,这就是为什么SIG_IGN
可以并且现在可以继承的原因。
推荐阅读
- angular - 推送功能中的离子问题
- javascript - 如何在特定行之后动态地将多行纯html添加到现有表中
- java - 如何避免在 Maven 中安装或部署仅测试模块
- python - 无法从需要登录的页面中抓取
- android - android Q中无法识别MediaProjection服务类型
- facebook - 提交至 Facebook 审核时应用被拒绝问题
- eclipse - 如何在 Eclipse 中恢复这个东西?
- c - readdir 如何返回指向 NEXT 文件信息的指针?
- python-2.7 - Celery 任务 on_success 处理程序的 kwargs 始终为空
- wordpress - 在 Wordpress 中集成 Bootstrap 4 Carousel