2011-11-26 42 views
3

我正在做一个简单的守护进程,它会在发送SIGINT和SIGTERM信号时发出日志,我可以在发出SIGTERM信号时记录日志,但当我尝试通过发送SIGINT信号按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。

+0

在命令行尝试'kill -INT '。 –

+3

可能值得指出的是,从信号处理程序中调用fopen()(或许多其他函数)并不安全。 –

回答

3

您无法将键盘生成的信号发送到守护程序。你将不得不去kill -INT它。

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

守护进程没有控制终端,它可以既不在前台也不在任何终端的后台。

5

由于守护进程根据定义没有在前台运行,因此当您按Ctrl + C时不是应用程序会获取SIGINT。 Ctrl + C仅影响前台应用程序。

+1

其实它并没有在后台运行。你看,终端可以有一个前台进程组和几个后台进程组。守护进程没有控制终端,因此它不能在任何终端的前台或后台。 – ninjalj

+0

好点。 Windows使我思考“背景”的方式不同:)编辑一下。 – cHao