⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daemon.cpp

📁 封装了实现守护进程的类
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <wait.h>
#include "Daemon.h"

static void sig_chld(int sig);

/*********************************************************************/

CDaemon::CDaemon()
:m_lockFile(-1)
{
}

CDaemon::~CDaemon()
{
	if(m_lockFile >= 0)
	{
		lockf(m_lockFile, F_ULOCK, 0);
		close(m_lockFile);
	}
}

bool CDaemon::Start(char *dir, char *lock)
{
	int child, i;

	//产生守护进程
	if(fork() != 0)
		exit(0);
	if(setsid() < 0)
		return false;
	//第二子进程不是会话长,禁止进程重新打开控制终端
	if(fork() != 0)
		exit(0);

	//关闭所有打开的句柄
	//子进程将从父进程继承所有句柄,如果不关闭将浪费系统资源
	for(i=0; i<DAEMON_MAXFILE; i++)
		close(i);
	//将stdin、stdout和stderr重定向到 /dev/null,避免使用标准输入输出设备产生问题
	open("/dev/null", O_RDWR); 
	dup(0);
	dup(0);
	//子进程从父进程继承文件掩模,将可能修改守护进程创建文件的位置,这里清除文件掩模
	umask(0);
	
	//忽略读tty异常
	signal(SIGTTIN, SIG_IGN);
	//忽略写tty异常
	signal(SIGTTOU, SIG_IGN);
	//忽略tty发送挂起请求
	signal(SIGTSTP, SIG_IGN);
	//避免僵尸进程
	signal(SIGCHLD, sig_chld);
	
	//如果不改变目录,则当前目录不可删除
	if(dir != NULL)
		chdir(dir);

	if(lock!=NULL && !lockfile(lock))
		return false;
	return true;
}

void CDaemon::Run(void *param)
{
	body(param);
}

/*******************************************************************/
bool CDaemon::lockfile(char *file)
{
	int len;
	char buf[256];
	
	if(m_lockFile >= 0)
		return true;
	m_lockFile = open(file, O_RDWR);
	if(m_lockFile < 0)
	{
		m_lockFile = open(file, O_RDWR|O_CREAT|O_TRUNC);
		if(m_lockFile < 0)
			return false;
	}
	if(lockf(m_lockFile, F_TLOCK, 0) < 0)
	{
		close(m_lockFile);
		m_lockFile = -1;
		return false;
	}
	len = sprintf(buf, "%d         \n", getpid());
	write(m_lockFile, buf, len);
	return true;
}

/*****************************************************************/

void sig_chld(int sig)
{
	int stat;
	waitpid(-1, &stat, WNOHANG);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -