UNP函数笔记十: 守护进程和inetd超级服务器

第十三章  守护进程和inetd超级服务器:

#include <syslog.h>
void syslog(int priority, const char * format, ...);

#include <syslog.h>
void openlog(const char * ident, int option, int facility);
void closelog(void);
    option:
        LOG_CONS,   LOG_NDELAY, LOG_NOWAIT, 
        LOG_ODELAY, LOG_PERROR, LOG_PID
    facility:
        LOG_AUTH,   LOG_AUTHPRIV, LOG_CRON,   LOG_DAEMON, 
        LOG_FTP,    LOG_KERN,     LOG_LOCAL0, LOG_LOCAL1, 
        LOG_LOCAL2, LOG_LOCAL3,   LOG_LOCAL4, LOG_LOCAL5, 
        LOG_LOCAL6, LOG_LOCAL7,   LOG_LPR,    LOG_MAIL, 
        LOG_NEWS,   LOG_SYSLOG,   LOG_USER,   LOG_UUCP
    level:
        LOG_EMERG,   LOG_ALERT,  LOG_CRIT, LOG_ERR, 
        LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG
    priority:
        facility | level
    %m: ("%s", strerror(errno))

示例:

#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>

#include "my_signal.h"

#define MAXFD  64

int 
daemon_init(const char * pname, int facility)
{
    int    i;
    pid_t  pid;

    if ((pid = fork()) < 0) {
        return(-1);
    }
    else if (pid > 0) {
        _exit(0);  /* parent terminates */
    }

    /* child 1 continues... */

    if (setsid() == -1) {  /* become session leader */
        return(-1);
    }

    my_signal(SIGHUP, SIG_IGN);
    if ((pid = fork()) < 0) {
        return(-1);
    }
    else if (pid > 0) {
        _exit(0);  /* child 1 terminates */
    }

    /* child 2 continues... */

    chdir("/");  /* change working directory */

    /* close off file descriptors */
    for (i = 0; i < MAXFD; i++) {
        close(i);
    }

    /* redirect stdin, stdout, and stderr to /dev/null */
    open("/dev/null", O_RDONLY);
    open("/dev/null", O_RDWR);
    open("/dev/null", O_RDWR);

    openlog(pname, LOG_PID, facility);

    return (0);  /* success */
}

#include <syslog.h>

void 
daemon_inetd(const char * pname, int facility)
{
    openlog(pname, LOG_PID, facility);
}

#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "sock_ntop.h"
#include "tcp_listen.h"
#include "daemon_init.h"

#define MAXLINE 4096

int
main(int argc, char ** argv)
{
    ssize_t           n;
    int               listenfd;
    int               connfd;
    socklen_t         addrlen;
    socklen_t         len;
    struct sockaddr * cliaddr;
    char            * ptr;
    char              buff[MAXLINE];
    time_t            ticks;

    if (argc < 2 || argc > 3) {
        printf("usage: daytimetcpsrv2 [ <host> ] <service or port>\n");
        exit(1);
    }

    daemon_init(argv[0], 0);

    /* need change "printf" to "syslog" in tcp_listen */
    if (argc == 2) {
        listenfd = tcp_listen(NULL, argv[1], &addrlen);
    }
    else {
        listenfd = tcp_listen(argv[1], argv[2], &addrlen);
    }

    if ((cliaddr = (struct sockaddr *)malloc(addrlen)) == NULL) {
        syslog(LOG_ERR, "malloc failed: %s", strerror(errno));
        exit(1);
    }

    for ( ; ; ) {
        len = addrlen;
        if ((connfd = accept(listenfd, cliaddr, &len)) == -1) {
            syslog(LOG_ERR, "accept error: %s", strerror(errno));
            exit(1);
        }

        if ((ptr = sock_ntop(cliaddr, len)) == NULL) {
            syslog(LOG_ERR, "sock_notp error: %s", strerror(errno));
            exit(1);
        }
        syslog(LOG_INFO, "connection from %s", ptr);

        ticks = time(NULL);
        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
        n = strlen(buff);
        if (write(connfd, buff, n) != n) {
            syslog(LOG_ERR, "write error: %s", strerror(errno));
            exit(1);
        }

        if (close(connfd) == -1) {
            syslog(LOG_ERR, "close error: %s", strerror(errno));
            exit(1);
        }
    }
}

#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "sock_ntop.h"
#include "daemon_inetd.h"

#define MAXLINE 4096

int 
main(int argc, char ** argv)
{
    ssize_t           n;
    socklen_t         len;
    struct sockaddr * cliaddr;
    char            * ptr;
    char              buff[MAXLINE];
    time_t            ticks;

    daemon_inetd(argv[0], 0);

    cliaddr = (struct sockaddr *)malloc(sizeof(struct sockaddr_storage));
    if (cliaddr == NULL) {
        syslog(LOG_ERR, "malloc failed: %s", strerror(errno));
        exit(1);
    }

    len = sizeof(struct sockaddr_storage);
    if (getpeername(0, cliaddr, &len) == -1) {
        syslog(LOG_ERR, "getpeername error: %s", strerror(errno));
        exit(1);
    }

    if ((ptr = sock_ntop(cliaddr, len)) == NULL) {
        syslog(LOG_ERR, "sock_notp error: %s", strerror(errno));
        exit(1);
    }
    syslog(LOG_INFO, "connection from %s", ptr);

    ticks = time(NULL);
    snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
    n = strlen(buff);
    if (write(0, buff, n) != n) {
        syslog(LOG_ERR, "write error: %s", strerror(errno));
        exit(1);
    }

    if (close(0) == -1) {  /* close TCP connection */
        syslog(LOG_ERR, "close error: %s", strerror(errno));
        exit(1);
    }

    free(cliaddr);
 
    exit(0);
}


你可能感兴趣的:(UNP函数笔记十: 守护进程和inetd超级服务器)