📄 daemon.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 + -