linux守护进程的几个关键地方
2014-03-11 18:01
405 查看
创建一个守护进程,有几个关键的步骤,也有几个地方需要注意,
几个关键的步骤有:
1:清除文件创建权限
2:调用fork,然后使父进程退出
3:调用setsid以创建一个新的会话,有三个目的使调用进程 a:成为新会话的首进程,b:成为新进程的组长进程,c:没有控制终端
4:切换工作目录
5:关闭不需要的文件描述符
需要注意的地方
1:因为守护进程没有控制终端,所以不能与标准输入输出出错进行交互,不能使用printf,通常用syslog来解决守护进程的打印信息
参考代码如下:
点击(此处)折叠或打开
#include <signal.h>
#include <stdlib.h>
#include <syslog.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/resource.h>
void daemonize(const char
*cmd)
{
int i, fd0, fd1, fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
/*
* Clear file creation mask.
*/
umask(0);
/*
* Get maximum number of file descriptors.
*/
if (getrlimit(RLIMIT_NOFILE,
&rl)
< 0)
printf("%s: can't get file limit", cmd);
/*
* Become a session leader
to lose controlling TTY.
*/
if ((pid
= fork())
< 0)
printf("%s: can't fork", cmd);
else if
(pid != 0)
/* parent
*/
exit(0);
setsid();
/*
* Ensure future opens won't allocate controlling TTYs.
*/
sa.sa_handler
= SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags
= 0;
if (sigaction(SIGHUP,
&sa,
NULL) < 0)
printf("can't ignore SIGHUP");
if ((pid
= fork())
< 0)
printf("%s: can't fork", cmd);
else if
(pid != 0)
/* parent
*/
exit(0);
/*
* Change the current working directory
to the root so
* we won't prevent file systems from being unmounted.
*/
if (chdir("/")
< 0)
printf("can't change directory to /");
/*
* Close all open file descriptors.
*/
if (rl.rlim_max
== RLIM_INFINITY)
rl.rlim_max
= 1024;
for (i
= 0; i
< rl.rlim_max; i++)
close(i);
/*
* Attach file descriptors 0, 1,
and 2 to
/dev/null.
*/
fd0 = open("/dev/null", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
/*
* Initialize the
log file.
*/
openlog(cmd, LOG_CONS, LOG_DAEMON);
if (fd0
!= 0
|| fd1 != 1
|| fd2
!= 2)
{
syslog(LOG_ERR,
"unexpected file descriptors %d %d %d",fd0, fd1, fd2);
exit(1);
}
syslog(LOG_DEBUG,
"daem ok ");
}
int main()
{
daemonize("test");
while(1);//守护进程所要干的事情
}
几个关键的步骤有:
1:清除文件创建权限
2:调用fork,然后使父进程退出
3:调用setsid以创建一个新的会话,有三个目的使调用进程 a:成为新会话的首进程,b:成为新进程的组长进程,c:没有控制终端
4:切换工作目录
5:关闭不需要的文件描述符
需要注意的地方
1:因为守护进程没有控制终端,所以不能与标准输入输出出错进行交互,不能使用printf,通常用syslog来解决守护进程的打印信息
参考代码如下:
点击(此处)折叠或打开
#include <signal.h>
#include <stdlib.h>
#include <syslog.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/resource.h>
void daemonize(const char
*cmd)
{
int i, fd0, fd1, fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
/*
* Clear file creation mask.
*/
umask(0);
/*
* Get maximum number of file descriptors.
*/
if (getrlimit(RLIMIT_NOFILE,
&rl)
< 0)
printf("%s: can't get file limit", cmd);
/*
* Become a session leader
to lose controlling TTY.
*/
if ((pid
= fork())
< 0)
printf("%s: can't fork", cmd);
else if
(pid != 0)
/* parent
*/
exit(0);
setsid();
/*
* Ensure future opens won't allocate controlling TTYs.
*/
sa.sa_handler
= SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags
= 0;
if (sigaction(SIGHUP,
&sa,
NULL) < 0)
printf("can't ignore SIGHUP");
if ((pid
= fork())
< 0)
printf("%s: can't fork", cmd);
else if
(pid != 0)
/* parent
*/
exit(0);
/*
* Change the current working directory
to the root so
* we won't prevent file systems from being unmounted.
*/
if (chdir("/")
< 0)
printf("can't change directory to /");
/*
* Close all open file descriptors.
*/
if (rl.rlim_max
== RLIM_INFINITY)
rl.rlim_max
= 1024;
for (i
= 0; i
< rl.rlim_max; i++)
close(i);
/*
* Attach file descriptors 0, 1,
and 2 to
/dev/null.
*/
fd0 = open("/dev/null", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
/*
* Initialize the
log file.
*/
openlog(cmd, LOG_CONS, LOG_DAEMON);
if (fd0
!= 0
|| fd1 != 1
|| fd2
!= 2)
{
syslog(LOG_ERR,
"unexpected file descriptors %d %d %d",fd0, fd1, fd2);
exit(1);
}
syslog(LOG_DEBUG,
"daem ok ");
}
int main()
{
daemonize("test");
while(1);//守护进程所要干的事情
}
相关文章推荐
- 精简Linux内核的一种方式--localmodconfig
- Ubuntu(Linux)使用Eclipse搭建C/C++编译环境
- Hyper-V安装RHEL或CENTOS后/dev/cdrom消失光驱无法使用的解决办法
- centos6.3下搭建samba文件共享服务器的汇总
- ARM+LINUX嵌入式系统的终端显示中文乱码解决
- 在Linux内核启动时打印时间
- Linux下rz,sz与ssh的配合使用
- linux进程调度方法
- linux安装mysql出错( file /usr/share/mysql/czech/errmsg.sys from install of MySQL-server-5.5.31-2.el6.i6)
- [Linux]第一部分-认识Linux及Linux主机规划与安装
- linux设备驱动——andriod平台wlan驱动
- linux 挂载 ISO 文件
- Linux mktime 源代码简析
- 在linux上进行php开发扩展
- 嵌入式Linux更改开机图片(小企鹅)
- CentOS上安装WordPress搭建博客平台
- Linux内核跟踪之syscall tracer
- Linux内核跟踪之trace框架分析
- Linux 的xargs命令
- Linux内核跟踪之ring buffer的实现