守护进程-学习demo

守护进程demo如下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LENGTH 128
char pid_name[] = "test";

static void start_daemon(const char *daemonName){
    pid_t pid;
    int fd,i,nullfd;
    char buf[64] = {0};
    char pid_file[LEN] = {0};

    if (!daemonName)
        exit(1);

    fprintf(stdout,"Starting %s...\n",daemonName);
    snprintf(pid_file,LENTGH,"/var/run/%s.pid",daemonName);
	// 一、调用fork,终止父进程,留下子进程
	// 1. 子进程继承了父进程的进程组ID
	// 2. 子进程不是进程组的头进程,可以调用setsid
    pid = fork();
    if(pid < 0){
        perror("Start daemon failed");
        exit(1);
    }else if(pid){
        exit(0);
    }
	// 二、调用setsid
	// 1.创建一个新的会话,<一>中的子进程1变为新会话的会话头进程
	// 2.以及新进程组的进程组头进程,进程与控制终端脱离
    setsid();
    
	// 三、禁止进程重新打开控制终端
	pid = fork();
    if(pid < 0){
        perror("Start daemon failed");
        exit(1);
    }else if(pid){
        exit(0);
    }
	// 四、为错误处理函数设置标识
	
	// 五、改变工作目录到根目录,若不更改目录,可能无法卸载所在的文件系统
    if(chdir("/")<0){
        perror("find workdir to proot failed");
        exit(1);
    }

    // 六、关闭所有打开的描述符
    // 1. 关闭继承过来的所有打开着的文件描述符
    for (i = 3; i <1024 ; i++) {
        close(i);
    }

	// 七、将stdin、stdout和stderr重定向到/dev/null
	// 1. 打开/dev/null作文本守护进程的标准输入、输出、和错误输出
	// 2. 确保这些描述符[0,1,2]打开,防止被其他套接字占用
    nullfd = open("/dev/null",O_RDWR);
    if(nullfd != -1){
        dup2(nullfd, STDIN_FILENO);
        dup2(nullfd, STDOUT_FILENO);
        dup2(nullfd, STDERR_FILENO);
        if(nullfd > 2)
            close(nullfd);
    } else{
        perror("Failed to open /dev/null");
        exit(1);
    }

    fd = open(pid_file,O_WRONLY|O_CREAT,0644);
    if(fd < 0){
        perror("Unable to create pid file");
        exit(1);
    }

    if(lockf(fd,F_TLOCK,0)<0){
        perror("Unable to lock pid file");
        exit(1);
    }

    if(ftruncate(fd,0)<0){
        perror("Failed to ftruncate the PID file");
        exit(1);
    }

    //sprintf(buf,"%d\n",(int)getpid());
    //printf("pid = %s\n",buf);
    if(write(fd,buf,strlen(buf))<strlen(buf)){
        perror("Failed to write pid to the file");
        exit(1);
    }
}


int main() {
    start_daemon(pid_name);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值