< 3;i)46{47close(i);48open("/dev/null", O_RDWR);49dup(0);50dup(0);51}52umask(0);53return;54}复制代码#include #include #include #include #include #include #include #define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while (0);void creat_daemon(void);int main(void){time_t t;int fd;creat_daemon();while(1){fd = open("daemon.log",O_WRONLY|O_CREAT|O_APPEND,0644);if(fd == -1)ERR_EXIT("open error");t = time(0);char *buf = asctime(localtime(&t));write(fd,buf,strlen(buf));close(fd);sleep(60);}return 0;}void creat_daemon(void){pid_t pid;pid = fork();if( pid == -1)ERR_EXIT("fork error");if(pid > 0 )exit(EXIT_SUCCESS);if(setsid() == -1)ERR_EXIT("SETSID ERROR");chdir("/");int i;for( i = 0; i < 3;i){close(i);open("/dev/null", O_RDWR);dup(0);dup(0);}umask(0);return;}结果:
文章插图
结果显示:当我一普通用户执行a.out时,进程表中并没有出现新创建的守护进程,但当我以root用户执行时,成功了,并在/目录下创建了daemon.log文件,cat查看后确实每个一分钟写入一次 。为什么只能root执行,那是因为当我们创建守护进程时,已经将当前目录切换我/目录,所以当我之后创建daemon.log文件是其实是在/目录下,那肯定不行,因为普通用户没有权限,或许你会问那为啥没报错呢?其实是有出错,只不过我们在创建守护进程时已经将标准输入关闭并重定向到/dev/null,所以看不到错误信息 。
四、利用库函数daemon()创建守护进程
其实我们完全可以利用daemon()函数创建守护进程,其函数原型:
#include int daemon(int nochdir, int noclose);DESCRIPTIONThe daemon() function is for programs wishing to detach themselves fromthe controlling terminal and run in the background as system daemons.If nochdir is zero, daemon()changestheprocess’scurrentworkingdirectory to the root directory ("/"); otherwise,Ifnoclose is zero, daemon() redirects standard input, standard outputand standard error to /dev/null; otherwise,nochangesaremadetothese file descriptors.功能:创建一个守护进程
参数:
nochdir:=0将当前目录更改至“/”
noclose:=0将标准输入、标准输出、标准错误重定向至“/dev/null”
返回值:
成功:0
失败:-1
现在我们利用daemon()改写刚才那个程序:
01#include 02#include 03#include 04#include 05#include 06#include 07#include 08#define ERR_EXIT(m) 09do10{11perror(m);12exit(EXIT_FAILURE);13}14while (0);15void creat_daemon(void);16int main(void)17{18time_t t;19int fd;20if(daemon(0,0) == -1)21ERR_EXIT("daemon error");22while(1){23fd = open("daemon.log",O_WRONLY|O_CREAT|O_APPEND,0644);24if(fd == -1)25ERR_EXIT("open error");26t = time(0);27char *buf = asctime(localtime(&t));28write(fd,buf,strlen(buf));29close(fd);30sleep(60);31}32return 0;33}复制代码#include #include #include #include #include #include #include #define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while (0);void creat_daemon(void);int main(void){time_t t;int fd;if(daemon(0,0) == -1)ERR_EXIT("daemon error");while(1){fd = open("daemon.log",O_WRONLY|O_CREAT|O_APPEND,0644);if(fd == -1)ERR_EXIT("open error");t = time(0);char *buf = asctime(localtime(&t));write(fd,buf,strlen(buf));close(fd);sleep(60);}return 0;}当daemon(0,0)时:
文章插图
结果同刚才一样,也是只有root才能成功,普通用户执行时看不到错误信息
现在让daemon(0,1),就是不关闭标准输入输出结果:
文章插图
可以看到错误信息
现在让daemon(1,0),就是不重定向,结果如下:
文章插图
这次普通用户执行成功了,以为没有切换到/目录下,有权限
推荐阅读