Daemonization和SIGHUP

时间:2016-08-23 14:22:59

标签: c linux signals daemon

http://www.masterraghu.com/subjects/np/introduction/unix_network_programming_v1.3/ch13lev1sec4.html (摘自Richard Steven的UNIX网络编程第1卷) 包括

Signal(SIGHUP, SIG_IGN);

作为daemon_init函数的一部分,因为:

  

..."我们必须忽略SIGHUP,因为当会话负责人终止(第一个孩子)时,会话中的所有进程(我们的第二个孩子)都会收到SIGHUP信号。"

该功能的核心是:

int     i;
pid_t     pid;

if ( (pid = Fork()) < 0)
    return (-1);
else if (pid)
    _exit(0);               /* parent terminates */

/* child 1 continues... */

if (setsid() < 0)           /* become session leader */
    return (-1);

Signal(SIGHUP, SIG_IGN);
if ( (pid = Fork()) < 0)
    return (-1);
else if (pid)
    _exit(0);               /* child 1 terminates */

/* child 2 continues... */

daemon_proc = 1;            /* for err_XXX() functions */

我不明白目标孩子为什么要获得大声

我尝试用一​​些信息打印来复制代码,以测试SIGHUP是否真的收到但是我似乎无法捕捉它,即使我停止(SIGSTOP)孙子进程,在这种情况下我认为它真的应该得到一个SIGHUP,因为这会导致孙子成为一个停止的孤儿进程组,但即使这样也没有收到SIGHUP(这显然与SIGSTOP部分有关:why SIGHUP signal not received when becoming an Orphaned Process Group)。

#define _GNU_SOURCE
#include <unistd.h>
#include <signal.h>
#include <stdio.h>

int daemon_proc = 0;

static void
pr_ids(char* name){
    printf("%s: pid = %ld, ppid = %ld, sid=%ld, pgrp = %ld, tpgrp = %ld\n",
            name, (long)getpid(), (long)getppid(), (long)getsid(getpid()), (long)getpgrp(),
            (long)tcgetpgrp(STDOUT_FILENO));
    fflush(stdout);
}
void hndlr(int s){
    static const char msg[] = "Caught SIGHUP\n";
    write(2,msg,sizeof(msg));
}
int daemon_init(){
    pid_t pid;
    pr_ids("gparent");

    if ( 0>(pid=fork()))
        return -1;
    if (pid) 
        _exit(0);

    pr_ids("parent");
    if (0>setsid())
        return -1;

    close(0);
    dup(1);

    if(0>sysv_signal(SIGHUP, hndlr))
        return -1;
    if(0>(pid=fork()))
        return -1;
    if(pid){
        sleep(1);
        _exit(0);
    }
    pr_ids("child");
    sleep(2);
    pr_ids("child");
    kill(getpid(), SIGSTOP);
    daemon_proc = 1;
    chdir("/");
    return 0;
}
int main(int argc, char** argv){
    daemon_init();
    printf("daemon_proc=%d\n", daemon_proc);
    return 0;
}

这给了我输出,如:

 gparent: pid = 20904, ppid = 20015, sid=20015, pgrp = 20904, tpgrp = 20904
 parent: pid = 20905, ppid = 1, sid=20015, pgrp = 20904, tpgrp = 20015
 child: pid = 20906, ppid = 20905, sid=20905, pgrp = 20905, tpgrp = -1
 #waiting
 child: pid = 20906, ppid = 1,   sid=20905, pgrp = 20905, tpgrp = -1

你能解释为什么第一个孩子(会话领导者)的自我终止应该导致第二个孩子的SIGHUP以及它为什么没有?

0 个答案:

没有答案