《Unix環境高級編程》學習之編寫守護進程

編寫規則:

1、調用umask將文件模式創建屏蔽字置爲一個已知值(通常是0),因爲屏蔽字會阻礙某些權限,影響保護進程的執行;

2、調用fork,然後父進程exit,保證當前進程不是進程組組長;

3、調用setsid,創建一個新的會話;

4、再次調用fork,退出父進程,保證守護進程不是會話首進程,這樣調用open重定向標準輸入、標準輸出、標準錯誤時,就不會被分配終端;

5、將當前工作目錄更改爲根目錄(並非必須的),因爲如果守護進程工作的目錄掛載在一個文件系統中,那麼該文件系統無法卸載;

6、關閉不需要的文件描述符;

7、重定向標準輸入、標準輸出、標準錯誤至/dev/null。


接下來是《Unix環境高級編程》中的一個例子:

#include "apue.h"
#include <syslog.h>
#include <fcntl.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)
	{
		err_quit("%s: can't get file limit", cmd);
	}

	/*
	 這一步fork保證進程不是進程組組長進程
	 */
	if ((pid = fork()) < 0)
	{
		err_quit("%s: can't fork", cmd);
	}
	else if (pid != 0) /* parent */
	{
		exit(0);
	}

	/*
	創建一個回話,會話只包含子進程,且子進程是會話首進程
	*/
	setsid();

	/*
	會話首進程的退出會出發SIGHUP信號
	默認此信號的操作會終止進程
	 */
	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if (sigaction(SIGHUP, &sa, NULL) < 0)
	{
		err_quit("%s: can't ignore SIGHUP", cmd);
	}

	/*
	再次創建子進程,退出父進程,保證守護進程不是會話首進程,這樣open的時候就不會被分配終端
	*/
	if ((pid = fork()) < 0)
	{
		err_quit("%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)
	{
		err_quit("%s: can't change directory to /", cmd);
	}

	/*
	 * 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);
	}

	/*
	 因爲前面關閉了所有的文件描述符,此時open返回的必定是最小的0,後面兩次dup返回的依次是1、2,也就完成了對標準輸入、標準輸出、標準錯誤重定向至/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);
	}
}




發佈了53 篇原創文章 · 獲贊 10 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章