APUE第十三章(守护进程)

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 写入日志之外还写入标准出错

PRIORITY
LOG_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;
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值