Ejemplo n.º 1
0
int TDaemon::WorkProc()
{
    struct sigaction sigact;
    sigset_t         sigset;
    int             signo;
    int             status;
    // сигналы об ошибках в программе будут обрататывать более тщательно
    // указываем что хотим получать расширенную информацию об ошибках
    sigact.sa_flags = SA_SIGINFO;
    // задаем функцию обработчик сигналов
    sigact.sa_sigaction = SelfDebug;

    sigemptyset(&sigact.sa_mask);

    // установим наш обработчик на сигналы
    sigaction(SIGFPE, &sigact, 0); // ошибка FPU
    sigaction(SIGILL, &sigact, 0); // ошибочная инструкция
    sigaction(SIGSEGV,&sigact, 0); // ошибка доступа к памяти
    sigaction(SIGBUS, &sigact, 0); // ошибка шины, при обращении к физической памяти

    sigemptyset(&sigset);
    
    // блокируем сигналы которые будем ожидать
    // сигнал остановки процесса пользователем
    sigaddset(&sigset, SIGQUIT);
    // сигнал для остановки процесса пользователем с терминала
    sigaddset(&sigset, SIGINT);
    // сигнал запроса завершения процесса
    sigaddset(&sigset, SIGTERM);
    // пользовательский сигнал который мы будем использовать для обновления конфига
    sigaddset(&sigset, SIGHUP); 
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    // Установим максимальное кол-во дискрипторов которое можно открыть
    SetFdLimit(FD_LIMIT);
    // запишем в лог, что наш демон стартовал
    //WriteLog("%s [DAEMON] Started\n", getTime());
    DaemonFunction();
        // цикл ожидания сообщений
        while(1)
        {
            // ждем указанных сообщений
            sigwait(&sigset, &signo);
            switch(signo)
            {
                // если это сообщение обновления конфига
                case SIGHUP:
                status = ReloadConfig();
                    if (status != 0)
                    {
                        WriteLog("%s [DAEMON] Reload config failed: %s\n", getTime(),strerror(errno));
                    }
                    else
                    {
                        WriteLog("%s [DAEMON] Reload config OK\n", getTime());
                    }
                break;
                
                case SIGQUIT:
                case SIGINT:
                case SIGTERM:
                default:
                    WriteLog("%s [DAEMON] Received signal %d\n", getTime(),signo);
                    WriteLog("%s [DAEMON] Stopped\n", getTime());
                    return CHILD_NEED_TERMINATE;
            }
        }
    WriteLog("%s [DAEMON] Stopped\n", getTime());
    
    // вернем код не требующим перезапуска
    return CHILD_NEED_TERMINATE;
}
Ejemplo n.º 2
0
int WorkProc() {
    struct sigaction sigact;
    sigset_t sigset;
    int signo;
    int status;

    // сигналы об ошибках в программе будут обрататывать более тщательно
    // указываем что хотим получать расширенную информацию об ошибках
    sigact.sa_flags = SA_SIGINFO;
    // задаем функцию обработчик сигналов
    sigact.sa_sigaction = signal_error;

    sigemptyset(&sigact.sa_mask);

    // установим наш обработчик на сигналы

    sigaction(SIGFPE, &sigact, 0); // ошибка FPU
    sigaction(SIGILL, &sigact, 0); // ошибочная инструкция
    sigaction(SIGSEGV, &sigact, 0); // ошибка доступа к памяти
    sigaction(SIGBUS, &sigact, 0); // ошибка шины, при обращении к физической памяти

    sigemptyset(&sigset);

    // блокируем сигналы которые будем ожидать
    // сигнал остановки процесса пользователем
    sigaddset(&sigset, SIGQUIT);

    // сигнал для остановки процесса пользователем с терминала
    sigaddset(&sigset, SIGINT);

    // сигнал запроса завершения процесса
    sigaddset(&sigset, SIGTERM);

    // пользовательский сигнал который мы будем использовать для обновления конфига
    sigaddset(&sigset, SIGUSR1);
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    // Установим максимальное кол-во дискрипторов которое можно открыть
    SetFdLimit(FD_LIMIT);

    // запишем в лог, что наш демон стартовал
    WriteLog("[DAEMON] Started\n");

    // запускаем все рабочие потоки
    status = InitWorkThread();
    if (status != -1) {
        // цикл ожижания сообщений
        for (; ;) {
            // ждем указанных сообщений
            sigwait(&sigset, &signo);

            // если то сообщение обновления конфига
            if (signo == SIGUSR1) {
                // обновим конфиг
                status = ReloadConfig();
                if (status == 0) {
                    WriteLog("[DAEMON] Reload config failed\n");
                }
                else {
                    WriteLog("[DAEMON] Reload config OK\n");
                }
            }
            else // если какой-либо другой сигнал, то выйдим из цикла
            {
                break;
            }
        }

        // остановим все рабочеи потоки и корректно закроем всё что надо
        DestroyWorkThread();
    }
    else {
        WriteLog("[DAEMON] Create work thread failed\n");
    }

    WriteLog("[DAEMON] Stopped\n");

    // вернем код не требующим перезапуска
    return CHILD_NEED_TERMINATE;
}