簡體   English   中英

為什么信號處理程序不處理信號

[英]Why the signal handler doesn't process the signal

我正在嘗試制作一個模擬命令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函數將捕獲的信號的處理方式重置為其默認處理方式。

執行時,過程映像將被破壞,並由新程序的過程映像替換。 在其中,指向傳遞給sigaction的handle_function的指針不再具有含義,或者至少不再具有舊含義。 唯一明智的操作系統可以處理的信號時做execve是將它們重置。

SIG_IGN的含義是通用的,獨立於當前程序,這就是SIG_IGN可以被繼承的原因。

execvp()execve()系統調用的前端。

從其Linux聯機幫助頁

除以下內容外,所有進程屬性均在execve()期間保留:

  * The dispositions of any signals that are being caught are reset to the default (signal(7)). 

因此,您安裝的信號處理程序將重置。

更正:(請參閱更改歷史記錄以獲取原始文本)

nohup(1)程序只是將progran名稱( nohup )及其選項從argc / argv參數轉移到main ,將stdout / stderr重定向到文件( nohup.out ),以防一個或兩個都指向一個文件。 tty設備,然后忽略SIGHUPexecvp(*argv, argv); 供原始程序執行。 它甚至根本不提供fork(2)

FreeBSD nohup的源代碼在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM