xref: /aosp_15_r20/external/libwebsockets/lwsws/main.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
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