poll() uses msecs as timeout
[elliptics.git] / example / ioserv.c
blob627821fa501edfafd64756f92ea2a07db5b1ec9f
1 /*
2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include <sys/wait.h>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <time.h>
32 #include <netinet/in.h>
34 #include "elliptics/packet.h"
35 #include "elliptics/interface.h"
37 #include "common.h"
39 #ifndef __unused
40 #define __unused __attribute__ ((unused))
41 #endif
43 static void dnet_usage(char *p)
45 fprintf(stderr, "Usage: %s\n"
46 " -c config - config file\n"
47 " -m - run under internal monitor\n"
48 " -l log - log file\n"
49 " -h - this help\n"
50 , p);
53 static int ioserv_monitor(void)
55 pid_t pid;
57 pid = fork();
58 if (pid == -1) {
59 fprintf(stderr, "Failed to fork to background: %s.\n", strerror(errno));
60 exit(pid);
63 if (pid != 0) {
64 printf("Children pid: %d\n", pid);
65 return pid;
67 setsid();
69 #if 0
70 close(0);
71 close(1);
72 close(2);
73 #endif
74 return 0;
77 static struct dnet_node *global_n;
78 static void ioserv_destroy_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
80 dnet_set_need_exit(global_n);
83 extern char *dnet_logger_value;
84 struct dnet_config_backend;
85 extern int dnet_set_log(struct dnet_config_backend *b __unused, char *key __unused, char *value);
87 static void ioserv_reload_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
89 dnet_set_log(NULL, NULL, dnet_logger_value);
92 static void ioserv_sigchild_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
94 int status, pid;
96 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
97 dnet_srw_update(global_n, pid);
101 static int ioserv_setup_signals(void)
103 struct sigaction sa;
105 memset(&sa, 0, sizeof(sa));
106 sa.sa_flags = SA_SIGINFO;
107 sa.sa_sigaction = ioserv_destroy_handler;
108 sigemptyset(&sa.sa_mask);
109 sigaction(SIGTERM, &sa, NULL);
110 sigaction(SIGINT, &sa, NULL);
112 sa.sa_flags = SA_SIGINFO;
113 sa.sa_sigaction = ioserv_reload_handler;
114 sigemptyset(&sa.sa_mask);
115 sigaction(SIGHUP, &sa, NULL);
117 sa.sa_flags = SA_SIGINFO;
118 sa.sa_sigaction = ioserv_sigchild_handler;
119 sigemptyset(&sa.sa_mask);
120 sigaction(SIGCHLD, &sa, NULL);
122 sigemptyset(&sa.sa_mask);
123 sigaddset(&sa.sa_mask, SIGTERM);
124 sigaddset(&sa.sa_mask, SIGINT);
125 sigaddset(&sa.sa_mask, SIGHUP);
126 sigaddset(&sa.sa_mask, SIGCHLD);
127 pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
128 sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
130 return 0;
133 static int ioserv_start(char *conf, int mon)
135 struct dnet_node *n;
137 n = dnet_parse_config(conf, mon);
138 if (!n)
139 return -1;
141 global_n = n;
142 ioserv_setup_signals();
144 while (!dnet_need_exit(n))
145 sleep(1);
147 dnet_server_node_destroy(n);
148 return 0;
151 int main(int argc, char *argv[])
153 int ch, mon = 0, err;
154 char *conf = NULL;
156 while ((ch = getopt(argc, argv, "mc:h")) != -1) {
157 switch (ch) {
158 case 'm':
159 mon = 1;
160 break;
161 case 'c':
162 conf = optarg;
163 break;
164 case 'h':
165 default:
166 dnet_usage(argv[0]);
167 return -1;
171 if (!conf) {
172 fprintf(stderr, "No config file provided. Exiting.\n");
173 return -1;
176 if (mon) {
177 #if 0
178 err = ioserv_monitor();
179 if (err > 0)
180 exit();
181 #endif
182 while (1) {
183 err = ioserv_monitor();
184 if (err > 0) {
185 int status;
187 waitpid(err, &status, 0);
189 err = WEXITSTATUS(status);
190 fprintf(stderr, "child exited with status: %d\n", err);
191 if (WIFEXITED(status)) {
192 printf("exited, status=%d\n", WEXITSTATUS(status));
193 } else if (WIFSIGNALED(status)) {
194 printf("killed by signal %d\n", WTERMSIG(status));
195 } else if (WIFSTOPPED(status)) {
196 printf("stopped by signal %d\n", WSTOPSIG(status));
197 } else if (WIFCONTINUED(status)) {
198 printf("continued\n");
200 } else {
201 exit(ioserv_start(conf, mon));
204 sleep(1);
206 } else {
207 ioserv_start(conf, mon);
210 return 0;