1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets web server application
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Written in 2010-2020 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker *
9*1c60b9acSAndroid Build Coastguard Worker * The person who associated a work with this deed has dedicated
10*1c60b9acSAndroid Build Coastguard Worker * the work to the public domain by waiving all of his or her rights
11*1c60b9acSAndroid Build Coastguard Worker * to the work worldwide under copyright law, including all related
12*1c60b9acSAndroid Build Coastguard Worker * and neighboring rights, to the extent allowed by law. You can copy,
13*1c60b9acSAndroid Build Coastguard Worker * modify, distribute and perform the work, even for commercial purposes,
14*1c60b9acSAndroid Build Coastguard Worker * all without asking permission.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * The test apps are intended to be adapted for use in your code, which
17*1c60b9acSAndroid Build Coastguard Worker * may be proprietary. So unlike the library itself, they are licensed
18*1c60b9acSAndroid Build Coastguard Worker * Public Domain.
19*1c60b9acSAndroid Build Coastguard Worker */
20*1c60b9acSAndroid Build Coastguard Worker #include "lws_config.h"
21*1c60b9acSAndroid Build Coastguard Worker
22*1c60b9acSAndroid Build Coastguard Worker #include <stdio.h>
23*1c60b9acSAndroid Build Coastguard Worker #include <stdlib.h>
24*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
25*1c60b9acSAndroid Build Coastguard Worker #include <getopt.h>
26*1c60b9acSAndroid Build Coastguard Worker #endif
27*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
28*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
29*1c60b9acSAndroid Build Coastguard Worker #include <sys/stat.h>
30*1c60b9acSAndroid Build Coastguard Worker #include <fcntl.h>
31*1c60b9acSAndroid Build Coastguard Worker #include <assert.h>
32*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
33*1c60b9acSAndroid Build Coastguard Worker #include <dirent.h>
34*1c60b9acSAndroid Build Coastguard Worker #include <syslog.h>
35*1c60b9acSAndroid Build Coastguard Worker #include <sys/time.h>
36*1c60b9acSAndroid Build Coastguard Worker #include <unistd.h>
37*1c60b9acSAndroid Build Coastguard Worker #include <sys/wait.h>
38*1c60b9acSAndroid Build Coastguard Worker #else
39*1c60b9acSAndroid Build Coastguard Worker #include <io.h>
40*1c60b9acSAndroid Build Coastguard Worker #include "gettimeofday.h"
41*1c60b9acSAndroid Build Coastguard Worker #include <uv.h>
42*1c60b9acSAndroid Build Coastguard Worker
fork(void)43*1c60b9acSAndroid Build Coastguard Worker int fork(void)
44*1c60b9acSAndroid Build Coastguard Worker {
45*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "Sorry Windows doesn't support fork().\n");
46*1c60b9acSAndroid Build Coastguard Worker return 0;
47*1c60b9acSAndroid Build Coastguard Worker }
48*1c60b9acSAndroid Build Coastguard Worker #endif
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard Worker #include <uv.h>
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_MALLOC_TRIM)
55*1c60b9acSAndroid Build Coastguard Worker #include <malloc.h>
56*1c60b9acSAndroid Build Coastguard Worker #endif
57*1c60b9acSAndroid Build Coastguard Worker
58*1c60b9acSAndroid Build Coastguard Worker static struct lws_context *context;
59*1c60b9acSAndroid Build Coastguard Worker static lws_sorted_usec_list_t sul_lwsws;
60*1c60b9acSAndroid Build Coastguard Worker static char config_dir[128], default_plugin_path = 1;
61*1c60b9acSAndroid Build Coastguard Worker static int opts = 0, do_reload = 1;
62*1c60b9acSAndroid Build Coastguard Worker static uv_loop_t loop;
63*1c60b9acSAndroid Build Coastguard Worker static uv_signal_t signal_outer[2];
64*1c60b9acSAndroid Build Coastguard Worker static int pids[32];
65*1c60b9acSAndroid Build Coastguard Worker void lwsl_emit_stderr(int level, const char *line);
66*1c60b9acSAndroid Build Coastguard Worker
67*1c60b9acSAndroid Build Coastguard Worker #define LWSWS_CONFIG_STRING_SIZE (64 * 1024)
68*1c60b9acSAndroid Build Coastguard Worker
69*1c60b9acSAndroid Build Coastguard Worker static const struct lws_extension exts[] = {
70*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_WITHOUT_EXTENSIONS)
71*1c60b9acSAndroid Build Coastguard Worker {
72*1c60b9acSAndroid Build Coastguard Worker "permessage-deflate",
73*1c60b9acSAndroid Build Coastguard Worker lws_extension_callback_pm_deflate,
74*1c60b9acSAndroid Build Coastguard Worker "permessage-deflate"
75*1c60b9acSAndroid Build Coastguard Worker },
76*1c60b9acSAndroid Build Coastguard Worker #endif
77*1c60b9acSAndroid Build Coastguard Worker { NULL, NULL, NULL /* terminator */ }
78*1c60b9acSAndroid Build Coastguard Worker };
79*1c60b9acSAndroid Build Coastguard Worker
80*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS)
81*1c60b9acSAndroid Build Coastguard Worker static const char * const plugin_dirs[] = {
82*1c60b9acSAndroid Build Coastguard Worker INSTALL_DATADIR"/libwebsockets-test-server/plugins/",
83*1c60b9acSAndroid Build Coastguard Worker NULL
84*1c60b9acSAndroid Build Coastguard Worker };
85*1c60b9acSAndroid Build Coastguard Worker #endif
86*1c60b9acSAndroid Build Coastguard Worker
87*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
88*1c60b9acSAndroid Build Coastguard Worker static struct option options[] = {
89*1c60b9acSAndroid Build Coastguard Worker { "help", no_argument, NULL, 'h' },
90*1c60b9acSAndroid Build Coastguard Worker { "debug", required_argument, NULL, 'd' },
91*1c60b9acSAndroid Build Coastguard Worker { "configdir", required_argument, NULL, 'c' },
92*1c60b9acSAndroid Build Coastguard Worker { "no-default-plugins", no_argument, NULL, 'n' },
93*1c60b9acSAndroid Build Coastguard Worker { NULL, 0, 0, 0 }
94*1c60b9acSAndroid Build Coastguard Worker };
95*1c60b9acSAndroid Build Coastguard Worker #endif
96*1c60b9acSAndroid Build Coastguard Worker
signal_cb(uv_signal_t * watcher,int signum)97*1c60b9acSAndroid Build Coastguard Worker void signal_cb(uv_signal_t *watcher, int signum)
98*1c60b9acSAndroid Build Coastguard Worker {
99*1c60b9acSAndroid Build Coastguard Worker switch (watcher->signum) {
100*1c60b9acSAndroid Build Coastguard Worker case SIGTERM:
101*1c60b9acSAndroid Build Coastguard Worker case SIGINT:
102*1c60b9acSAndroid Build Coastguard Worker break;
103*1c60b9acSAndroid Build Coastguard Worker
104*1c60b9acSAndroid Build Coastguard Worker case SIGHUP:
105*1c60b9acSAndroid Build Coastguard Worker if (lws_context_is_deprecated(context))
106*1c60b9acSAndroid Build Coastguard Worker return;
107*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("Dropping listen sockets\n");
108*1c60b9acSAndroid Build Coastguard Worker lws_context_deprecate(context, NULL);
109*1c60b9acSAndroid Build Coastguard Worker return;
110*1c60b9acSAndroid Build Coastguard Worker
111*1c60b9acSAndroid Build Coastguard Worker default:
112*1c60b9acSAndroid Build Coastguard Worker signal(SIGABRT, SIG_DFL);
113*1c60b9acSAndroid Build Coastguard Worker abort();
114*1c60b9acSAndroid Build Coastguard Worker break;
115*1c60b9acSAndroid Build Coastguard Worker }
116*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Signal %d caught\n", watcher->signum);
117*1c60b9acSAndroid Build Coastguard Worker uv_signal_stop(watcher);
118*1c60b9acSAndroid Build Coastguard Worker uv_signal_stop(&signal_outer[1]);
119*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(context);
120*1c60b9acSAndroid Build Coastguard Worker }
121*1c60b9acSAndroid Build Coastguard Worker
122*1c60b9acSAndroid Build Coastguard Worker static void
lwsws_min(lws_sorted_usec_list_t * sul)123*1c60b9acSAndroid Build Coastguard Worker lwsws_min(lws_sorted_usec_list_t *sul)
124*1c60b9acSAndroid Build Coastguard Worker {
125*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s\n", __func__);
126*1c60b9acSAndroid Build Coastguard Worker
127*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_MALLOC_TRIM)
128*1c60b9acSAndroid Build Coastguard Worker malloc_trim(4 * 1024);
129*1c60b9acSAndroid Build Coastguard Worker #endif
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(context, 0, &sul_lwsws, lwsws_min, 60 * LWS_US_PER_SEC);
132*1c60b9acSAndroid Build Coastguard Worker }
133*1c60b9acSAndroid Build Coastguard Worker
134*1c60b9acSAndroid Build Coastguard Worker static int
context_creation(void)135*1c60b9acSAndroid Build Coastguard Worker context_creation(void)
136*1c60b9acSAndroid Build Coastguard Worker {
137*1c60b9acSAndroid Build Coastguard Worker int cs_len = LWSWS_CONFIG_STRING_SIZE - 1;
138*1c60b9acSAndroid Build Coastguard Worker struct lws_context_creation_info info;
139*1c60b9acSAndroid Build Coastguard Worker char *cs, *config_strings;
140*1c60b9acSAndroid Build Coastguard Worker void *foreign_loops[1];
141*1c60b9acSAndroid Build Coastguard Worker
142*1c60b9acSAndroid Build Coastguard Worker cs = config_strings = malloc(LWSWS_CONFIG_STRING_SIZE);
143*1c60b9acSAndroid Build Coastguard Worker if (!config_strings) {
144*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Unable to allocate config strings heap\n");
145*1c60b9acSAndroid Build Coastguard Worker return -1;
146*1c60b9acSAndroid Build Coastguard Worker }
147*1c60b9acSAndroid Build Coastguard Worker
148*1c60b9acSAndroid Build Coastguard Worker memset(&info, 0, sizeof(info));
149*1c60b9acSAndroid Build Coastguard Worker
150*1c60b9acSAndroid Build Coastguard Worker info.external_baggage_free_on_destroy = config_strings;
151*1c60b9acSAndroid Build Coastguard Worker info.pt_serv_buf_size = 8192;
152*1c60b9acSAndroid Build Coastguard Worker info.options = (uint64_t)((uint64_t)opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |
153*1c60b9acSAndroid Build Coastguard Worker LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
154*1c60b9acSAndroid Build Coastguard Worker LWS_SERVER_OPTION_LIBUV);
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS)
157*1c60b9acSAndroid Build Coastguard Worker if (default_plugin_path)
158*1c60b9acSAndroid Build Coastguard Worker info.plugin_dirs = plugin_dirs;
159*1c60b9acSAndroid Build Coastguard Worker #endif
160*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("Using config dir: \"%s\"\n", config_dir);
161*1c60b9acSAndroid Build Coastguard Worker
162*1c60b9acSAndroid Build Coastguard Worker /*
163*1c60b9acSAndroid Build Coastguard Worker * first go through the config for creating the outer context
164*1c60b9acSAndroid Build Coastguard Worker */
165*1c60b9acSAndroid Build Coastguard Worker if (lwsws_get_config_globals(&info, config_dir, &cs, &cs_len))
166*1c60b9acSAndroid Build Coastguard Worker goto init_failed;
167*1c60b9acSAndroid Build Coastguard Worker
168*1c60b9acSAndroid Build Coastguard Worker foreign_loops[0] = &loop;
169*1c60b9acSAndroid Build Coastguard Worker info.foreign_loops = foreign_loops;
170*1c60b9acSAndroid Build Coastguard Worker info.pcontext = &context;
171*1c60b9acSAndroid Build Coastguard Worker
172*1c60b9acSAndroid Build Coastguard Worker context = lws_create_context(&info);
173*1c60b9acSAndroid Build Coastguard Worker if (context == NULL) {
174*1c60b9acSAndroid Build Coastguard Worker lwsl_err("libwebsocket init failed\n");
175*1c60b9acSAndroid Build Coastguard Worker goto init_failed;
176*1c60b9acSAndroid Build Coastguard Worker }
177*1c60b9acSAndroid Build Coastguard Worker
178*1c60b9acSAndroid Build Coastguard Worker /*
179*1c60b9acSAndroid Build Coastguard Worker * then create the vhosts... protocols are entirely coming from
180*1c60b9acSAndroid Build Coastguard Worker * plugins, so we leave it NULL
181*1c60b9acSAndroid Build Coastguard Worker */
182*1c60b9acSAndroid Build Coastguard Worker
183*1c60b9acSAndroid Build Coastguard Worker info.extensions = exts;
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker if (lwsws_get_config_vhosts(context, &info, config_dir, &cs, &cs_len))
186*1c60b9acSAndroid Build Coastguard Worker return 1;
187*1c60b9acSAndroid Build Coastguard Worker
188*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(context, 0, &sul_lwsws, lwsws_min, 60 * LWS_US_PER_SEC);
189*1c60b9acSAndroid Build Coastguard Worker
190*1c60b9acSAndroid Build Coastguard Worker return 0;
191*1c60b9acSAndroid Build Coastguard Worker
192*1c60b9acSAndroid Build Coastguard Worker init_failed:
193*1c60b9acSAndroid Build Coastguard Worker free(config_strings);
194*1c60b9acSAndroid Build Coastguard Worker
195*1c60b9acSAndroid Build Coastguard Worker return 1;
196*1c60b9acSAndroid Build Coastguard Worker }
197*1c60b9acSAndroid Build Coastguard Worker
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker /*
200*1c60b9acSAndroid Build Coastguard Worker * root-level sighup handler
201*1c60b9acSAndroid Build Coastguard Worker */
202*1c60b9acSAndroid Build Coastguard Worker
203*1c60b9acSAndroid Build Coastguard Worker static void
reload_handler(int signum)204*1c60b9acSAndroid Build Coastguard Worker reload_handler(int signum)
205*1c60b9acSAndroid Build Coastguard Worker {
206*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
207*1c60b9acSAndroid Build Coastguard Worker int m;
208*1c60b9acSAndroid Build Coastguard Worker
209*1c60b9acSAndroid Build Coastguard Worker switch (signum) {
210*1c60b9acSAndroid Build Coastguard Worker
211*1c60b9acSAndroid Build Coastguard Worker case SIGHUP: /* reload */
212*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "root process receives reload\n");
213*1c60b9acSAndroid Build Coastguard Worker if (!do_reload) {
214*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "passing HUP to child processes\n");
215*1c60b9acSAndroid Build Coastguard Worker for (m = 0; m < (int)LWS_ARRAY_SIZE(pids); m++)
216*1c60b9acSAndroid Build Coastguard Worker if (pids[m])
217*1c60b9acSAndroid Build Coastguard Worker kill(pids[m], SIGHUP);
218*1c60b9acSAndroid Build Coastguard Worker sleep(1);
219*1c60b9acSAndroid Build Coastguard Worker }
220*1c60b9acSAndroid Build Coastguard Worker do_reload = 1;
221*1c60b9acSAndroid Build Coastguard Worker break;
222*1c60b9acSAndroid Build Coastguard Worker case SIGINT:
223*1c60b9acSAndroid Build Coastguard Worker case SIGTERM:
224*1c60b9acSAndroid Build Coastguard Worker case SIGKILL:
225*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "parent process waiting 2s...\n");
226*1c60b9acSAndroid Build Coastguard Worker sleep(2); /* give children a chance to deal with the signal */
227*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "killing service processes\n");
228*1c60b9acSAndroid Build Coastguard Worker for (m = 0; m < (int)LWS_ARRAY_SIZE(pids); m++)
229*1c60b9acSAndroid Build Coastguard Worker if (pids[m])
230*1c60b9acSAndroid Build Coastguard Worker kill(pids[m], SIGTERM);
231*1c60b9acSAndroid Build Coastguard Worker exit(0);
232*1c60b9acSAndroid Build Coastguard Worker }
233*1c60b9acSAndroid Build Coastguard Worker #else
234*1c60b9acSAndroid Build Coastguard Worker // kill() implementation needed for WIN32
235*1c60b9acSAndroid Build Coastguard Worker #endif
236*1c60b9acSAndroid Build Coastguard Worker }
237*1c60b9acSAndroid Build Coastguard Worker
main(int argc,char ** argv)238*1c60b9acSAndroid Build Coastguard Worker int main(int argc, char **argv)
239*1c60b9acSAndroid Build Coastguard Worker {
240*1c60b9acSAndroid Build Coastguard Worker int n = 0, budget = 100, debug_level = 1024 + 7;
241*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
242*1c60b9acSAndroid Build Coastguard Worker int m;
243*1c60b9acSAndroid Build Coastguard Worker int status;//, syslog_options = LOG_PID | LOG_PERROR;
244*1c60b9acSAndroid Build Coastguard Worker #endif
245*1c60b9acSAndroid Build Coastguard Worker
246*1c60b9acSAndroid Build Coastguard Worker strcpy(config_dir, "/etc/lwsws");
247*1c60b9acSAndroid Build Coastguard Worker while (n >= 0) {
248*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
249*1c60b9acSAndroid Build Coastguard Worker n = getopt_long(argc, argv, "hd:c:n", options, NULL);
250*1c60b9acSAndroid Build Coastguard Worker #else
251*1c60b9acSAndroid Build Coastguard Worker n = getopt(argc, argv, "hd:c:n");
252*1c60b9acSAndroid Build Coastguard Worker #endif
253*1c60b9acSAndroid Build Coastguard Worker if (n < 0)
254*1c60b9acSAndroid Build Coastguard Worker continue;
255*1c60b9acSAndroid Build Coastguard Worker switch (n) {
256*1c60b9acSAndroid Build Coastguard Worker case 'd':
257*1c60b9acSAndroid Build Coastguard Worker debug_level = atoi(optarg);
258*1c60b9acSAndroid Build Coastguard Worker break;
259*1c60b9acSAndroid Build Coastguard Worker case 'n':
260*1c60b9acSAndroid Build Coastguard Worker default_plugin_path = 0;
261*1c60b9acSAndroid Build Coastguard Worker break;
262*1c60b9acSAndroid Build Coastguard Worker case 'c':
263*1c60b9acSAndroid Build Coastguard Worker lws_strncpy(config_dir, optarg, sizeof(config_dir));
264*1c60b9acSAndroid Build Coastguard Worker break;
265*1c60b9acSAndroid Build Coastguard Worker case 'h':
266*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "Usage: lwsws [-c <config dir>] "
267*1c60b9acSAndroid Build Coastguard Worker "[-d <log bitfield>] [--help] "
268*1c60b9acSAndroid Build Coastguard Worker "[-n]\n");
269*1c60b9acSAndroid Build Coastguard Worker exit(1);
270*1c60b9acSAndroid Build Coastguard Worker }
271*1c60b9acSAndroid Build Coastguard Worker }
272*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
273*1c60b9acSAndroid Build Coastguard Worker /*
274*1c60b9acSAndroid Build Coastguard Worker * We leave our original process up permanently, because that
275*1c60b9acSAndroid Build Coastguard Worker * suits systemd.
276*1c60b9acSAndroid Build Coastguard Worker *
277*1c60b9acSAndroid Build Coastguard Worker * Otherwise we get into problems when reload spawns new processes and
278*1c60b9acSAndroid Build Coastguard Worker * the original one dies randomly.
279*1c60b9acSAndroid Build Coastguard Worker */
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker signal(SIGHUP, reload_handler);
282*1c60b9acSAndroid Build Coastguard Worker signal(SIGINT, reload_handler);
283*1c60b9acSAndroid Build Coastguard Worker
284*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "Root process is %u\n", (unsigned int)getpid());
285*1c60b9acSAndroid Build Coastguard Worker
286*1c60b9acSAndroid Build Coastguard Worker while (1) {
287*1c60b9acSAndroid Build Coastguard Worker if (do_reload) {
288*1c60b9acSAndroid Build Coastguard Worker do_reload = 0;
289*1c60b9acSAndroid Build Coastguard Worker n = fork();
290*1c60b9acSAndroid Build Coastguard Worker if (n == 0) /* new */
291*1c60b9acSAndroid Build Coastguard Worker break;
292*1c60b9acSAndroid Build Coastguard Worker /* old */
293*1c60b9acSAndroid Build Coastguard Worker if (n > 0)
294*1c60b9acSAndroid Build Coastguard Worker for (m = 0; m < (int)LWS_ARRAY_SIZE(pids); m++)
295*1c60b9acSAndroid Build Coastguard Worker if (!pids[m]) {
296*1c60b9acSAndroid Build Coastguard Worker pids[m] = n;
297*1c60b9acSAndroid Build Coastguard Worker break;
298*1c60b9acSAndroid Build Coastguard Worker }
299*1c60b9acSAndroid Build Coastguard Worker }
300*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
301*1c60b9acSAndroid Build Coastguard Worker sleep(2);
302*1c60b9acSAndroid Build Coastguard Worker
303*1c60b9acSAndroid Build Coastguard Worker n = waitpid(-1, &status, WNOHANG);
304*1c60b9acSAndroid Build Coastguard Worker if (n > 0)
305*1c60b9acSAndroid Build Coastguard Worker for (m = 0; m < (int)LWS_ARRAY_SIZE(pids); m++)
306*1c60b9acSAndroid Build Coastguard Worker if (pids[m] == n) {
307*1c60b9acSAndroid Build Coastguard Worker pids[m] = 0;
308*1c60b9acSAndroid Build Coastguard Worker break;
309*1c60b9acSAndroid Build Coastguard Worker }
310*1c60b9acSAndroid Build Coastguard Worker #else
311*1c60b9acSAndroid Build Coastguard Worker // !!! implemenation needed
312*1c60b9acSAndroid Build Coastguard Worker #endif
313*1c60b9acSAndroid Build Coastguard Worker }
314*1c60b9acSAndroid Build Coastguard Worker #endif
315*1c60b9acSAndroid Build Coastguard Worker /* child process */
316*1c60b9acSAndroid Build Coastguard Worker
317*1c60b9acSAndroid Build Coastguard Worker lws_set_log_level(debug_level, lwsl_emit_stderr_notimestamp);
318*1c60b9acSAndroid Build Coastguard Worker
319*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("lwsws libwebsockets web server - license CC0 + MIT\n");
320*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("(C) Copyright 2010-2020 Andy Green <[email protected]>\n");
321*1c60b9acSAndroid Build Coastguard Worker
322*1c60b9acSAndroid Build Coastguard Worker #if (UV_VERSION_MAJOR > 0) // Travis...
323*1c60b9acSAndroid Build Coastguard Worker uv_loop_init(&loop);
324*1c60b9acSAndroid Build Coastguard Worker #else
325*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "Your libuv is too old!\n");
326*1c60b9acSAndroid Build Coastguard Worker return 0;
327*1c60b9acSAndroid Build Coastguard Worker #endif
328*1c60b9acSAndroid Build Coastguard Worker uv_signal_init(&loop, &signal_outer[0]);
329*1c60b9acSAndroid Build Coastguard Worker uv_signal_start(&signal_outer[0], signal_cb, SIGINT);
330*1c60b9acSAndroid Build Coastguard Worker uv_signal_init(&loop, &signal_outer[1]);
331*1c60b9acSAndroid Build Coastguard Worker uv_signal_start(&signal_outer[1], signal_cb, SIGHUP);
332*1c60b9acSAndroid Build Coastguard Worker
333*1c60b9acSAndroid Build Coastguard Worker if (context_creation()) {
334*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Context creation failed\n");
335*1c60b9acSAndroid Build Coastguard Worker return 1;
336*1c60b9acSAndroid Build Coastguard Worker }
337*1c60b9acSAndroid Build Coastguard Worker
338*1c60b9acSAndroid Build Coastguard Worker lws_service(context, 0);
339*1c60b9acSAndroid Build Coastguard Worker
340*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: closing\n", __func__);
341*1c60b9acSAndroid Build Coastguard Worker
342*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < 2; n++) {
343*1c60b9acSAndroid Build Coastguard Worker uv_signal_stop(&signal_outer[n]);
344*1c60b9acSAndroid Build Coastguard Worker uv_close((uv_handle_t *)&signal_outer[n], NULL);
345*1c60b9acSAndroid Build Coastguard Worker }
346*1c60b9acSAndroid Build Coastguard Worker
347*1c60b9acSAndroid Build Coastguard Worker /* cancel the per-minute sul */
348*1c60b9acSAndroid Build Coastguard Worker lws_sul_cancel(&sul_lwsws);
349*1c60b9acSAndroid Build Coastguard Worker
350*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(context);
351*1c60b9acSAndroid Build Coastguard Worker (void)budget;
352*1c60b9acSAndroid Build Coastguard Worker #if (UV_VERSION_MAJOR > 0) // Travis...
353*1c60b9acSAndroid Build Coastguard Worker while ((n = uv_loop_close(&loop)) && --budget)
354*1c60b9acSAndroid Build Coastguard Worker uv_run(&loop, UV_RUN_ONCE);
355*1c60b9acSAndroid Build Coastguard Worker #endif
356*1c60b9acSAndroid Build Coastguard Worker
357*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "lwsws exited cleanly: %d\n", n);
358*1c60b9acSAndroid Build Coastguard Worker
359*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32
360*1c60b9acSAndroid Build Coastguard Worker closelog();
361*1c60b9acSAndroid Build Coastguard Worker #endif
362*1c60b9acSAndroid Build Coastguard Worker
363*1c60b9acSAndroid Build Coastguard Worker context = NULL;
364*1c60b9acSAndroid Build Coastguard Worker
365*1c60b9acSAndroid Build Coastguard Worker return 0;
366*1c60b9acSAndroid Build Coastguard Worker }
367