UNIX环境高级编程——初始化一个守护进程

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
/* 创建守护进程函数 */
int daemonize(){
	int childpid, fd, fdtablesize;
	int error, in, out;
	/* 忽略终端I/O信号,STOP信号 */
	signal(SIGTTOU, SIG_IGN); /* 后台进程写控制终端 */
	signal(SIGTTIN, SIG_IGN); /* 后台进程读控制终端 */
	signal(SIGTSTP, SIG_IGN); /* 终端挂起 */
	signal(SIGHUP, SIG_IGN); /* 进程组长退出时向所有会议成员发出的 */
	/* 父进程退出,子进程成为孤儿进程 */
	if (fork()!=0)
	    exit(1);
	/* 设置新会话的领头进程,并与原来的登录会话和进程组脱离 */
	if (setsid() == -1) 
	    exit(1);
	/* 防止会话组长重新申请控制终端,子进程退出,孙进程没有控制终端了 */
	if (fork()!=0)
	    exit(1);
	/* 关闭打开的文件描述符,防止资源浪费和防止引起无法预料的错误 */
	for (fd = 3, fdtablesize = getdtablesize();fd < fdtablesize;fd++){	
		close(fd);
	}
	/* 重定向标准输入/标准输出和标准错误输出 */
	error = open("./stderr", O_WRONLY|O_CREAT, 0600);
	dup2(error, 2);
	close(error);
	in = open("./stdin", O_RDONLY|O_CREAT,0600);
	dup2(in, 0);
	close(in);
	out = open("./stdout", O_WRONLY|O_CREAT,0600);
	dup2(out, 1);
	close(out);
	/* 可以改变工作目录 */
	/* chdir("/"); */
	/* 重设文件创建掩模 */
	umask(0);
	/* 忽略SIGCHLD信号, 防止僵尸进程 */
	signal(SIGCHLD, SIG_IGN);
	return 0;
}
int main(void){
	time_t now;
	daemonize();
	openlog("MyMsgDaemon", LOG_CONS | LOG_PID, 0);
	syslog(LOG_DEBUG, "守护进程测试/n");
	while (1){
		time(&now);
		syslog(LOG_DEBUG, "守护进程测试, 当前时间:[%s]/n", ctime(&now));
		sleep(6);	
	}
	return 0;
}	

原文地址:https://www.cnblogs.com/wangfengju/p/6172497.html