Advanced Programming in UNIX Environment Episode 69

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-06 14:59:28
#include "apue.h"
#include <pthread.h>
#include <syslog.h>

sigset_t mask;

extern int already_running(void);

void reread(void)
{

}

void *thr_fn(void *arg)
{
    int err, signo;

    for(;;)
    {
        err=sigwait(&mask,&signo);
        if(err!=0)
        {
            syslog(LOG_ERR,"sigwait fialed");
            return 1;
        }

        switch(signo)
        {
            case SIGHUP:
                syslog(LOG_INFO,"Re-reading configuration file");
                reread();
                break;
            case SIGTERM:
                syslog(LOG_INFO,"got SIGTERM; exiting");
                return 0;
            default:
                syslog(LOG_INFO,"unexpected signal %d\n", signo);
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    int err;
    pthread_t tid;
    char *cmd;
    struct sigaction sa;

    if((cmd=strrchr(argv[0],'/'))==NULL)
        cmd=argv[0];
    else
        cmd++;

    daemonzie(cmd);

    if(already_running())
    {
        syslog(LOG_ERR,"deamon already running");
        return 1;
    }

    sa.sa_handler=SIG_DFL;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags=0;
    if(sigaction(SIGHUP,&sa,NULL)<0)
        err_quit("%s: can't restore SIGHUP default");

    sigfillset(&mask);
    if((err=pthread_sigmask(SIG_BLOCK,&mask,NULL))!=0)
        err_exit(err,"SIG_BLOCK error");

    err=pthread_create(&tid,NULL,thr_fn,0);
    if(err!=0)
        err_exit(err,"can't create thread");
    
    return 0;
}

Daemon rereading configuration files

#include "apue.h"
#include <syslog.h>
#include <errno.h>

extern int lockfile(int);
extern int already_running(void);

void reread(void)
{

}

void sigterm(int signo)
{
    syslog(LOG_INFO,"get SIGTERM; exiting");
    return 0;
}

void sighup(int signo)
{
    syslog(LOG_INFO, "Re-reading configuration file");
    reread();
}

int main(int argc, char *argv[])
{
    char *cmd;
    struct sigaction sa;

    if((cmd=strrchr(argv[0],'/'))==NULL)
        cmd=argv[0];
    else
        cmd++;

    daemonize(cmd);

    if(already_running())
    {
        syslog(LOG_ERR,"daemon already running");
        return 1;
    }

    sa.sa_handler=sigterm;
    sigemptyset(&sa.sa_mask);
    sigaddset(&sa.sa_mask,SIGHUP);
    sa.sa_flags=0;
    if(sigaction(SIGTERM,&sa,NULL)<0)
    {
        syslog(LOG_ERR,"can't catch SIGTERM: %s"strerror(errno));
        return 1;
    }
    sa.sa_handler=sighup;
    sigemptyset(&sa.sa_mask);

    sigaddset(&sa.sa_mask,SIGTERM);
    sa.sa_flags=0;
    if(sigaction(SIGHUP,&sa,NULL)<0)
    {
        syslog(LOG_ERR,"can't catch SIGHUP: %s", strerror(errno));
        return 1;
    }

    return 0;
}

Alternative implementation of daemon rereading configuration files

Client–Server Model

A common use for a daemon process is as a server process. Indeed, in Figure 13.2, we can call the syslogd process a server that has messages sent to it by user processes (clients) using a UNIX domain datagram socket.

In general, a server is a process that waits for a client to contact it, requesting some type of service.

#include "apue.h"
#include <fcntl.h>

int set_cloexec(int fd)
{
    int val;

    if((val=fcntl(fd, F_GETFD,0))<0)
        return -1;
    
    val|=FD_CLOEXEC;

    return fcntl(fd,F_SETFD,val);
}

Set close-on-exec flag

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!