守护进程

#include <stdio.h>

#include <stdlib.h>
#include <unistd.h>        //open()
#include <signal.h>        //sigaction()
#include <fcntl.h>        
#include <syslog.h>        //openlog()
#include <stdarg.h>        //openlog() arguments
#include <sys/time.h>        //getrlimit()
#include <sys/resource.h>    //getrlimit()
#include <sys/stat.h>        //umask()
#include <sys/types.h>        //umask
#include <string.h>
#include <errno.h>

void daemonize(const char *cmd);

int main(int argc, char *argv[])
{
    fprintf(stdout,
            "parent id:%d, parent group id: %d, parent session id: %d\n",
            getpid(), getgid(), getsid());

    daemonize("daemon");

    return 0;
}

void daemonize(const char *cmd)
{
    int i, fd0, fd1, fd2;
    pid_t pid;
    struct rlimit rl;
    struct sigaction sa;

    /*
     * Clear file creation mask; 创建守护进程第一步,设置文件创建屏蔽字
     * */
    umask(0);

    /*
     * Get maximum number of file descriptors
     * */
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
    {
        fprintf(stderr, "%s can't get file limit.%s\n", cmd, strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*
     * Become a session leader to lose controling TTY. 创建守护进程第1.5步,创建子进程,父进程退出
     * */
    if ((pid = fork()) < 0)
    {
        fprintf(stderr, "%s can't fork:%s", cmd, strerror(errno));
        exit(EXIT_FAILURE);
    } else if (pid != 0)
    {
        //parent exit
        exit(0);
    }
//创建守护进程第3步,将子进程加入新会话,
    setsid();

    /*
     * Ensure future opens won't allocate controlling TTYs.  忽略SIGHUP信号,此信号是终端创建和退出时发生的
     * */
#if 0
    struct sigaction
    {
        void (*sa_handler) (int);
        void (*sa_sigaction) (int, siginfo_t *, void *);
        sigset_t sa_mask;
        int sa_flags;
        void (*sa_restorer) (void);
    };
#endif
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if(sigaction(SIGHUP, &sa, NULL) < 0)
    {
        fprintf(stdout, "%s can't ignore SIGUP\n", cmd);

        exit(EXIT_FAILURE);

    }

 if((pid = fork()) < 0)   //创建守护进程第2步,创建子进程,父进程退出
    {
        fprintf(stderr, "%s can't fork:%s", cmd, strerror(errno));
        exit(EXIT_FAILURE);
    }
    else if(pid != 0)
    {
        //parent exit.
        exit(0);
    }

    /*
     * Change the current workint directory to the root so we won't prevent
     * file systems from begin unmounted.创建守护进程第4步,改变工作路径到根,预防文件系统卸载
     * */
    if(chdir("/") < 0)
    {
        fprintf(stderr, "%s: can't change directory to /\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*
     * Close all open file descriptors, RLIM_INFINITY is 资源无限制,创建守护进程第5步,关闭所有的文件描述符
     * */
    if(rl.rlim_max == RLIM_INFINITY)
    {
        rl.rlim_max = 1024;
    }
    for(i = 0; i < rl.rlim_max; ++i)
    {
        close(i);
    }

    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.创建守护进程第6步,重定向0,1,2到/dev/null
     * */
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    /*
     * Initialize the log file.
     * */
    openlog(cmd, LOG_CONS, LOG_DAEMON);
    if(fd0 !=0 || fd1 != 1 || fd2 != 2)
    {
        syslog(LOG_ERR, "unexcptioned file descriptors %d %d %d",fd0, fd1, fd2);
        exit(1);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值