APUE第十三章(守护进程)

来源:互联网 发布:传奇网站源码 编辑:程序博客网 时间:2024/05/30 05:40

1.日志

/*****************************************包含头文件:  #include <syslog.h>函数原型:   void openlog(const char* ident,int option,int facility);void syslog(int priority,const char* format,….);void closelog(void);int setlogmask(int maskpri);返回值:前日志记录优先级屏蔽字值OPTIONS:       LOG_PID   加上进程标识符 LOG_CON如果消息无法记录日志文件就发到控制台LOG_NDELAY 第一次调用syslog立即打开日志功能LOG_WAIT 不等待将消息记入日志可能已创建的子进程LOG_ODELAY  第一条日志消息记录打开之前延迟打开至syslogd守护进程的连接LOG_PERROR 写入日志之外还写入标准出错PRIORITYLOG_ERRERG             紧急(最高优先级)LOG_ALERT                必须立即恢复的情况LOG_CRIT                    严重情况(如硬件设备出错)LOG_ERR                     出错情况LOG_WARNING          警告情况LOG_NOTICE                正常但重要的情况LOG_INFO                      信息性消息LOG_DEBUG                  调试消息*****************************************/

vi 13.1.c

#include <stdio.h>#include <stdlib.h>#include <syslog.h>int main(){    char* buf = "not exist";    FILE* fp;    fp = fopen(buf,"r");    if (!fp)    {    syslog(LOG_ERR | LOG_USER,"%m\n");    }    return 0;}

这里写图片描述

2.守护进程

1.初始化守护进程
1.设置特定文件创建屏蔽字
2.调用fork 退出父进程
3.调用setsid使调用进程成为会话首进程 fork 使子进程无控制终端 退出调用进程
4.屏蔽可能唤起控制台的信号
5.关闭不再需要的文件描述符
6.将当前工作目录更改为根目录
7.进行日志管理

vi 13.2.c

#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>#include <sys/resource.h>#include <syslog.h>#include <fcntl.h>#include <sys/stat.h>void daemonize(const char* cmd){    struct rlimit rl;    struct sigaction sa;    pid_t pid;    int fd0,fd1,fd2;    umask(0);    if (getrlimit(RLIMIT_NOFILE,&rl) < 0)    {    printf("getrlimit error\n");    exit(0);    }    if ((pid = fork()) < 0)    {    printf("fork error\n");    exit(0);    }    else if (pid != 0)    exit(0);    setsid();    sa.sa_handler = SIG_IGN;    sigemptyset(&sa.sa_mask);    sa.sa_flags = 0;    if (sigaction(SIGHUP,&sa,NULL) < 0)    {    printf("sigaction error\n");    exit(0);    }    if ((pid = fork()) < 0)    {    printf("fork error\n");    exit(0);    }    else if (pid != 0)    exit(0);    if (chdir("/") < 0)    {    printf("chdir error\n");    exit(0);    }    if(rl.rlim_max == RLIM_INFINITY)    rl.rlim_max = 1024;    for (int i = 0; i < rl.rlim_max; ++i)    close(i);    umask(0);    fd0 = open("/dev/null",O_RDWR);    fd1 = dup(0);    fd2 = dup(0);    openlog(cmd,LOG_CONS,LOG_DAEMON);    if (fd0 != 0 || fd1 != 1 || fd2 != 2)    {    syslog(LOG_ERR,"unexpect file descripttors %d %d %d",fd0,fd1,fd2);    exit(1);    }}int main(){    daemonize("13.2.out");    sleep(1000);    return 0;}

这里写图片描述

3.守护进程配置文件及单副本运行

include <sys/resource.h>#include <stdlib.h>#include <sys/stat.h>#include <syslog.h>#include <signal.h>#include <string.h>#include <errno.h>#include <pthread.h>#include <unistd.h>#include <stdio.h>#include <fcntl.h>#define LOCKFILE "/var/run/mydaemon.conf"#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)sigset_t mask;int lockfile(int fd){    struct flock fl;    fl.l_type = F_RDLCK;    fl.l_whence = SEEK_SET;    fl.l_start = 0;    fl.l_len = 0;    return fcntl(fd,F_SETLK,&fl);}int single_run(){    int fd = open(LOCKFILE,O_RDWR | O_CREAT,LOCKMODE);    if (fd < 0)    {    syslog(LOG_ERR,"%s %d\n",strerror(errno),fd);    exit(1);    }    if (lockfile(fd) < 0)    {    syslog(LOG_ERR,"%s\n",strerror(errno));    return -1;    }    ftruncate(fd,0);    char buf[100];    sprintf(buf,"PPID:  %ld  PID: %ld",(long)getpid(),(long)getppid());    write(fd,buf,strlen(buf) + 1);    return  0;}void* signal_handler(void* arg){    int err,signo;    for (; ;)    {    sigwait(&mask,&signo);    switch(signo)    {        case SIGHUP:        syslog(LOG_ERR,"try hup\n");        break;        case SIGTERM:        exit(0);        default:        syslog(LOG_ERR,"unexpected signal\n");    }    }}void mydaemon(const char* cmd){    struct rlimit rl;    struct sigaction sa;    if (getrlimit(RLIMIT_NOFILE,&rl) < 0)    {    syslog(LOG_ERR,"getrlimit error\n");    exit(1);    }    umask(0);    pid_t pid;    if ((pid = fork()) < 0)    {    syslog(LOG_ERR,"first fork error\n");    exit(1);    }else if (pid > 0)    exit(0);    setsid();    sa.sa_handler = SIG_IGN;    sigemptyset(&sa.sa_mask);    sa.sa_flags = 0;    if (sigaction(SIGHUP,&sa,NULL) < 0)    {    syslog(LOG_ERR,"first sigaction error\n");    exit(1);    }    if ((pid = fork()) < 0)    {    syslog(LOG_ERR,"second fork error\n");    exit(1);    }else if (pid > 0)    exit(0);    if (chdir("/") < 0)    {    syslog(LOG_ERR,"chdir error\n");    exit(1);    }    if (rl.rlim_max == RLIM_INFINITY)    rl.rlim_max = 1024;    for (int i = 0; i < rl.rlim_max; ++i)    close(i);    int fd0,fd1,fd2;    fd0 = open("/dev/null",O_RDWR);    fd1 = dup(0);    fd2 = dup(0);    openlog(cmd,LOG_CONS,LOG_DAEMON);    if (fd0 != 0 || fd1 != 1 || fd2 != 2)    {    syslog(LOG_ERR,"unexpected file destription error\n");    exit(1);    }}int main(){    struct sigaction sa;    mydaemon("mydaemond");    if (single_run() < 0)    {    syslog(LOG_ERR,"dummy has been run\n");    exit(1);    }    sa.sa_handler = SIG_DFL;    sigemptyset(&sa.sa_mask);    sa.sa_flags = 0;    if (sigaction(SIGHUP,&sa,NULL) < 0)    {    syslog(LOG_ERR,"sigaction error\n");    exit(1);    }    sigfillset(&mask);    if (pthread_sigmask(SIG_SETMASK,&mask,NULL) !=  0)    {    syslog(LOG_ERR,"sigprocmask error\n");    exit(1);    }    pthread_t tid;    if (pthread_create(&tid,NULL,signal_handler,NULL) !=  0)    {    syslog(LOG_ERR,"pthread_create error\n");    exit(1);    }    while (1)    sleep(100);    return 0;}

这里写图片描述