Вызов демонизирующей функции из основного цикла?

0

Поэтому я пишу программу, которая будет работать как фоновый процесс в системе Linux, и я создавал функцию демона, чтобы начать процесс в фоновом режиме. Мне нужно знать, должен ли я объявлять объект внутри основного класса для запуска функции daemonize, или должен ли я сделать daemonize funciton, и это две вспомогательные функции static. Код ниже, есть ли лучший способ сделать это или один из способов более предпочтительный, чем другой? Благодарю.

#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
}
Теги:

1 ответ

1

Современные демоны не должны основываться на себе. Вместо этого просто запустите его на переднем плане и позвольте вызывающему абоненту (то есть сценарию под именем /etc/init.d) выбрать его демонизацию - обычно используется start-stop-daemon(8), хотя systemd может сделать это самостоятельно,

  • 0
    Я не получаю понижающий голос?!? Это хорошо отвечает на вопрос "Код ниже, есть ли лучший способ сделать это или один метод предпочтительнее другого?"
  • 0
    Это кажется вполне разумным ответом. Если вам нужно выполнить некоторую логику перед запуском демона, поместите его в скрипт /etc/init.d (проверка файлов PID или что у вас есть). Процесс должен быть демоном, а не менеджером демона; у нас есть дюжина инструментов для этого, и нет никаких причин, по которым ваша служба заставляла меня писать еще один пользовательский класс Puppet. Чем менее вы умны, тем более вероятно, что это сработает, а это очень просто.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню