Linux守护进程示例

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <sys/resource.h>
#include <syslog.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>


#define LOCKFILE "deamon0.pid"
#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
sigset_t mask;


static void re_read(void)
{
/*do anything*/
}
static int lockfile(int fd)
{
struct flock lock;

lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;

return(fcntl(fd, F_SETLK, &lock));
}
static int already_running(void)
{
int fd;
char buf[16];

fd = open(LOCKFILE, O_RDWR | O_CREAT, LOCKMODE);
if(fd < 0){
syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
_exit(100);
}
if(lockfile(fd) < 0){
if(errno == EAGAIN || errno == EACCES){
close(fd);
return(1);
}
syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno));
_exit(1);
}
ftruncate(fd, 0);
sprintf(buf, "%lu", (unsigned long)getpid());
write(fd, buf, strlen(buf) + 1);

return 0;
}
static void _daemon(const char *str)
{
int i, fd0, fd1, fd2;
pid_t pid;
struct rlimit rl;
struct sigaction  sa;

//clear file creation mask
umask(0);
if(getrlimit(RLIMIT_NOFILE, &rl) < 0){
printf("%s: can't get file limit\n", str);
_exit(1);
}
//become a session leader to lose controlling TTY
if((pid = fork()) < 0){
printf("%s: can't fork\n", str);
_exit(1);
}else if(pid > 0)
_exit(1);
setsid();
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP, &sa, NULL) < 0){
printf("%s: can't catch SIGHUP\n", str);
_exit(1);
}
//change current wirding directory
if(chdir("."/*or other*/) < 0){
printf("%s: can't chmod\n", str);
_exit(1);
}
if((pid = fork()) < 0){
printf("%s: can't fork\n", str);
_exit(1);
}else if(pid > 0)
_exit(1);
//close all file descriptor
if(rl.rlim_max == RLIM_INFINITY)
rl.rlim_max = 1024;
for(i = 0; i < rl.rlim_max; i++)
close(i);
//attach file descriptor 0, 1, 2 to /dev/null
fd0 = open("/dev/null", O_RDWR);
fd1 = dup(fd0);
fd2 = dup(fd0);
openlog(str, LOG_CONS, LOG_DAEMON);
if(fd0 != 0 || fd1 != 1|| fd2 != 2){
syslog(LOG_ERR, "unexpected file descriptor %d %d %d", fd0, fd1, fd2);
_exit(1);
}
}
static void *thr_proc_hup(void *arg)
{
int err, signo;


while(1){
err = sigwait(&mask, &signo);
if(err != 0){
syslog(LOG_ERR, "sigwait failed");
_exit(1);
}
switch(signo){
case SIGHUP:
syslog(LOG_INFO, "re-reading configuration file");
re_read();
break;
case SIGTERM:
syslog(LOG_INFO, "catch SIGTERM, exiting");
_exit(1);
default:
break;
}
}


return((void *)0);
}
int main(int argc, char *argv[])
{
int err;
pthread_t tid;
struct sigaction sa;


_daemon(argv[0]);
if(already_running()){
syslog(LOG_ERR, "deamon already running");
_exit(1);
}
sigfillset(&mask);
sigdelset(&mask, SIGKILL);
sigdelset(&mask, SIGSTOP);
if((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) < 0){
syslog(LOG_ERR, "can't pthread_sigmask");
}
err = pthread_create(&tid, NULL, thr_proc_hup, NULL);
if(err != 0){
syslog(LOG_ERR, "can't pthread_create");
_exit(1);
}


while(1){
/*do anything*/;
}


return(0);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值