第十三章 守护进程和inetd超级服务器:
#include <syslog.h> void syslog(int priority, const char * format, ...); #include <syslog.h> void openlog(const char * ident, int option, int facility); void closelog(void); option: LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY, LOG_PERROR, LOG_PID facility: LOG_AUTH, LOG_AUTHPRIV, LOG_CRON, LOG_DAEMON, LOG_FTP, LOG_KERN, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NEWS, LOG_SYSLOG, LOG_USER, LOG_UUCP level: LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG priority: facility | level %m: ("%s", strerror(errno))
#include <fcntl.h> #include <unistd.h> #include <syslog.h> #include "my_signal.h" #define MAXFD 64 int daemon_init(const char * pname, int facility) { int i; pid_t pid; if ((pid = fork()) < 0) { return(-1); } else if (pid > 0) { _exit(0); /* parent terminates */ } /* child 1 continues... */ if (setsid() == -1) { /* become session leader */ return(-1); } my_signal(SIGHUP, SIG_IGN); if ((pid = fork()) < 0) { return(-1); } else if (pid > 0) { _exit(0); /* child 1 terminates */ } /* child 2 continues... */ chdir("/"); /* change working directory */ /* close off file descriptors */ for (i = 0; i < MAXFD; i++) { close(i); } /* redirect stdin, stdout, and stderr to /dev/null */ open("/dev/null", O_RDONLY); open("/dev/null", O_RDWR); open("/dev/null", O_RDWR); openlog(pname, LOG_PID, facility); return (0); /* success */ }
#include <syslog.h> void daemon_inetd(const char * pname, int facility) { openlog(pname, LOG_PID, facility); }
#include <time.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include "sock_ntop.h" #include "tcp_listen.h" #include "daemon_init.h" #define MAXLINE 4096 int main(int argc, char ** argv) { ssize_t n; int listenfd; int connfd; socklen_t addrlen; socklen_t len; struct sockaddr * cliaddr; char * ptr; char buff[MAXLINE]; time_t ticks; if (argc < 2 || argc > 3) { printf("usage: daytimetcpsrv2 [ <host> ] <service or port>\n"); exit(1); } daemon_init(argv[0], 0); /* need change "printf" to "syslog" in tcp_listen */ if (argc == 2) { listenfd = tcp_listen(NULL, argv[1], &addrlen); } else { listenfd = tcp_listen(argv[1], argv[2], &addrlen); } if ((cliaddr = (struct sockaddr *)malloc(addrlen)) == NULL) { syslog(LOG_ERR, "malloc failed: %s", strerror(errno)); exit(1); } for ( ; ; ) { len = addrlen; if ((connfd = accept(listenfd, cliaddr, &len)) == -1) { syslog(LOG_ERR, "accept error: %s", strerror(errno)); exit(1); } if ((ptr = sock_ntop(cliaddr, len)) == NULL) { syslog(LOG_ERR, "sock_notp error: %s", strerror(errno)); exit(1); } syslog(LOG_INFO, "connection from %s", ptr); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); n = strlen(buff); if (write(connfd, buff, n) != n) { syslog(LOG_ERR, "write error: %s", strerror(errno)); exit(1); } if (close(connfd) == -1) { syslog(LOG_ERR, "close error: %s", strerror(errno)); exit(1); } } }
#include <time.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include "sock_ntop.h" #include "daemon_inetd.h" #define MAXLINE 4096 int main(int argc, char ** argv) { ssize_t n; socklen_t len; struct sockaddr * cliaddr; char * ptr; char buff[MAXLINE]; time_t ticks; daemon_inetd(argv[0], 0); cliaddr = (struct sockaddr *)malloc(sizeof(struct sockaddr_storage)); if (cliaddr == NULL) { syslog(LOG_ERR, "malloc failed: %s", strerror(errno)); exit(1); } len = sizeof(struct sockaddr_storage); if (getpeername(0, cliaddr, &len) == -1) { syslog(LOG_ERR, "getpeername error: %s", strerror(errno)); exit(1); } if ((ptr = sock_ntop(cliaddr, len)) == NULL) { syslog(LOG_ERR, "sock_notp error: %s", strerror(errno)); exit(1); } syslog(LOG_INFO, "connection from %s", ptr); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); n = strlen(buff); if (write(0, buff, n) != n) { syslog(LOG_ERR, "write error: %s", strerror(errno)); exit(1); } if (close(0) == -1) { /* close TCP connection */ syslog(LOG_ERR, "close error: %s", strerror(errno)); exit(1); } free(cliaddr); exit(0); }