简体   繁体   中英

Calling a daemonizing function from a main loop?

So I'm writing a program that's going to be running as a background process in a Linux system and I've been setting up a daemon function to begin with to run the process in the background. What I need to know is whether I should declare an object inside the main class to run the daemonize function or whether I should make the daemonize funciton and it's two sub functions static. The code is below, is there any better way to do this or is one method more preferable than another? thanks.

#include "../Headers/LogMonitor.h"

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

LogMonitor::LogMonitor() {
    // TODO Auto-generated constructor stub

}

LogMonitor::~LogMonitor() {
    // TODO Auto-generated destructor stub
}

int main( int argc, const char* argv[] )
{
    // Daemonize the program to run in the background
    LogMonitor::daemonize();
}

void LogMonitor::signal_handler(int sig)
{
    switch(sig) {
    case SIGHUP:
        log_message(LOG_FILE,"hangup signal caught");
        break;
    case SIGTERM:
        log_message(LOG_FILE,"terminate signal caught");
        exit(0);
        break;
    }
}

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

void LogMonitor::daemonize()
{
    int i,lfp;
    char str[10];

    if(getppid()==1) return;    // Check if already a daemon

    i = fork();
    if (i < 0) exit(1);         // Fork error
    if (i > 0) exit(0);         // Parent exits

    setsid();                   // Obtain a new process group

    for (i = getdtablesize(); i >= 0; --i) close(i);    // Close all descriptors

    i = open("/dev/null",O_RDWR);                       // stdin
    dup(i);                                             // stdout
    dup(i);                                             // stderr

    umask(027);                                         // Set newly created file permissions

    chdir(RUNNING_DIR);                                 // Change running directory

    lfp = open("exampled.lock",O_RDWR|O_CREAT,0640);
    if (lfp < 0) exit(1);                               // Can't open
    if (lockf(lfp,F_TLOCK,0) < 0) exit(0);              // Can't lock
    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(SIGHUP,  LogMonitor::signal_handler);                    // Catch hangup signal
    signal(SIGTERM, LogMonitor::signal_handler);                    // Catch kill signal
}

Modern daemons should not background themselves. Instead, just run it in the foreground and let the caller (ie the script under /etc/init.d ) choose to daemonize it - start-stop-daemon(8) is in common use, although systemd can do it on its own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM