UNP関数ノート10:デーモンプロセスとinetdスーパーサーバ
5642 ワード
第13章デーモンプロセスと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>
");
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
", 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
", 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);
}