- 论坛徽章:
- 1
|
在APUE中,daemonize函数用于初始化一个守护进程,在这个过程中,经历两次fork,同时两次退出父进程。ruptimed函数调用daemonize函数,我觉得调用daemonize函数的进程退出,所以ruptimed里面位于daemonize之后的代码都不会被执行,但明显这不是作者的原意,但我又找不出我思路错误的原因,还清各位指点。
daemonize函数:- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <syslog.h>
- #include <fcntl.h>
- #include <sys/resource.h>
- #include <signal.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 maxmum number of file descriptors;
- */
- if(getrlimit(RLIMIT_NOFILE, &rl) < 0) {
- printf("%s can't get file limit", cmd);
- exit(1);
- }
- /*
- *become a session leader to lose controlling TTY;
- */
- if((pid = fork()) < 0) {
- perror("fork error");
- exit(1);
- } else if(pid != 0)
- exit(0);
- printf("child1");
- setsid();
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if(sigaction(SIGHUP, &sa, NULL) < 0) {
- perror("sigaction error");
- exit(1);
- }
- if((pid = fork()) < 0) {
- perror("fork error");
- exit(1);
- } else if(pid != 0)
- exit(0);
- printf("child2");
- if(chdir("/") < 0)
- perror("can't change directory to /");
- if(rl.rlim_max == RLIM_INFINITY)
- rl.rlim_max = 1024;
- for(i = 0; i < rl.rlim_max; i++)
- close(i);
- 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 descriptors %d %d %d", fd0, fd1, fd2);
- exit(1);
- }
- }
复制代码 ruptimed函数:- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <syslog.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <errno.h>
- #define BUFLEN 128
- #define QLEN 10
- #ifndef HOST_NAME_MAX
- #define HOST_NAME_MAX 256
- #endif
- extern int initserver(int, struct sockaddr *, socklen_t , int);
- void
- serve(int sockfd)
- {
- int clfd;
- FILE *fp;
- char buf[BUFLEN];
- for(;;) {
- clfd = accept(sockfd, NULL, NULL);
- if(clfd < 0) {
- syslog(LOG_ERR, "ruptime: accept error:%s",
- strerror(errno));
- exit(1);
- }
- if((fp = popen("/usr/bin/uptime", "r")) == NULL) {
- sprintf(buf, "error:%s\n", strerror(errno));
- send(clfd, buf, strlen(buf), 0);
- } else {
- while(fgets(buf, BUFLEN, fp) != NULL)
- send(clfd, buf, strlen(buf), 0);
- pclose(fp);
- }
- close(clfd);
- }
- }
- int
- main(int argc, char *argv[])
- {
- struct addrinfo *ailist, *aip;
- struct addrinfo hint;
- int sockfd, err, n;
- char *host;
- if(argc != 1) {
- printf("usage: ruptimed");
- exit(1);
- }
- #ifdef _SC_HOST_NAME_MAX
- n = sysconf(_SC_HOST_NAME_MAX);
- if(n < 0)
- #endif
- n = HOST_NAME_MAX;
- host = malloc(n);
- if(host == NULL) {
- perror("malloc error");
- exit(1);
- }
- if(gethostname(host, n) < 0) {
- perror("gethostname error");
- exit(1);
- }
- printf("host : %s\n", host);
- printf("pid: %d\n", getpid());
- daemonize("ruptimed");
- [color=Red]printf("pid: %d\n", getpid());
- hint.ai_flags = AI_CANONNAME;
- hint.ai_family = 0;
- hint.ai_socktype = SOCK_STREAM;
- hint.ai_protocol = 0;
- hint.ai_addrlen = 0;
- hint.ai_canonname = NULL;
- hint.ai_next = NULL;
- printf("--------------\n");
- if((err = getaddrinfo(host, "ruptime", &hint, &ailist)) != 0) {
- syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s", gai_strerror(err));
- exit(1);
- }
- printf("--------------\n");
- for(aip = ailist; aip != NULL; aip = aip->ai_next) {
- if((sockfd = initserver(SOCK_STREAM, aip->ai_addr, aip->ai_addrlen, QLEN)) >= 0) {
- serve(sockfd);
- exit(0);
- }
- }
- exit(1);[/color]
- }
复制代码 也就是说红色部分的代码都不会再执行,因为当前进程作为daemonize中的父进程已经退出。 |
|