守护进程无法注册SIGINT信号。

3

我正在制作一个简单的守护进程,当接收到SIGINT和SIGTERM信号时会生成日志。我已经可以在接收到SIGTERM信号时记录日志,但是当我尝试通过按下Ctrl+C来获得SIGINT信号时,似乎没有发出信号,因为它没有保存在日志中。此外,在我尝试发送SIGINT信号时,守护进程仍在运行。

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>

#define RUNNING_DIR "/tmp"
#define LOCK_FILE   "simple_daemon.lock"
#define LOG_FILE    "simple_daemon.log"

void log_message(filename,message)
char *filename;
char *message;
{
    FILE *logfile;
    logfile=fopen(filename,"a");
    if(!logfile) return;
    fprintf(logfile,"%s\n",message);
    fclose(logfile);
}   

void signal_handler(sig)
int sig;
{
    switch(sig) {

    case SIGTERM:
        log_message(LOG_FILE,"received a SIGTERM signal");
        exit(0);
        break;
    case SIGINT:
        log_message(LOG_FILE, "received a SIGINT signal");
        exit(0);
        break;
    }
}

void daemonize()
{
    int i,lfp;
    char str[10];
    if(getppid()==1) return; /* already a daemon */
    i=fork();
    if (i<0) exit(1); /* fork error */
    if (i>0) exit(0); /* parent exits */
    /* child (daemon) continues */
    setsid(); /* obtain a new process group */
    for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
    i=open("/dev/null",O_RDWR); /* open stdin */
    dup(i); /* open stdout */
    dup(i); /* open stderr */
    umask(027); /* set newly created file permissions */
    chdir(RUNNING_DIR); /* change running directory */
    lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
    if (lfp<0) exit(1); /* can not open */
    if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* can not lock */
    /* first instance continues */
    sprintf(str,"%d\n",getpid());
    write(lfp,str,strlen(str)); /* record pid to lockfile */
    signal(SIGCHLD,SIG_IGN); /* ignore child */
    signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
    signal(SIGTTOU,SIG_IGN);
    signal(SIGTTIN,SIG_IGN);
    signal(SIGTERM,signal_handler); /* catch kill signal */
    signal(SIGINT,signal_handler); /* catch kill signal */
}

main()
{
    daemonize();
    while(1) sleep(1); /* run */
}

我无法找到代码的任何问题,我正在使用Ubuntu 11.04。


在命令行上尝试使用“kill -INT <pid>”。 - Nikolai Fetissov
3
值得指出的是,在信号处理程序中调用 fopen()(或许多其他函数)是不安全的。 - Richard Kettlewell
2个回答

5

由于守护进程定义上不在前台运行,因此当您按下Ctrl + C时,它不会影响守护进程接收到SIGINT信号,只会影响前台应用程序。


1
实际上它甚至没有在后台运行。你知道,一个终端可以有一个前台进程组和几个后台进程组。守护进程没有控制终端,因此它既不能在任何终端的前台也不能在后台。 - ninjalj
好的观点。Windows 让我对“后台”有了不同的思考 :) 稍微编辑了一下。 - cHao

3

你不能向守护程序发送键盘生成的信号。您必须使用kill -INT来结束它。

终端可以有一个前台进程组和多个后台进程组。键盘生成的信号将被发送到前台进程组。

守护程序没有控制终端,因此无法成为任何终端的前台或后台进程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接