Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1711689433, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"f295c37ca93f6fb10ee8e245e0ba756d", "oid":{ "oid": "e4be3317ee421f951fb16a85c7edacc9b8a0e6aa", "alias": [ "refs/heads/main"]},"blobname": "lwsws/main.c", "blob": "/*\n * libwebsockets web server application\n *\n * Written in 2010-2020 by Andy Green \u003candy@warmcat.com\u003e\n *\n * This file is made available under the Creative Commons CC0 1.0\n * Universal Public Domain Dedication.\n *\n * The person who associated a work with this deed has dedicated\n * the work to the public domain by waiving all of his or her rights\n * to the work worldwide under copyright law, including all related\n * and neighboring rights, to the extent allowed by law. You can copy,\n * modify, distribute and perform the work, even for commercial purposes,\n * all without asking permission.\n *\n * The test apps are intended to be adapted for use in your code, which\n * may be proprietary.\tSo unlike the library itself, they are licensed\n * Public Domain.\n */\n#include \u0022lws_config.h\u0022\n\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\n#include \u003cgetopt.h\u003e\n#endif\n#include \u003csignal.h\u003e\n#include \u003cstring.h\u003e\n#include \u003csys/stat.h\u003e\n#include \u003cfcntl.h\u003e\n#include \u003cassert.h\u003e\n#ifndef _WIN32\n#include \u003cdirent.h\u003e\n#include \u003csyslog.h\u003e\n#include \u003csys/time.h\u003e\n#include \u003cunistd.h\u003e\n#include \u003csys/wait.h\u003e\n#else\n#include \u003cio.h\u003e\n#include \u0022gettimeofday.h\u0022\n#include \u003cuv.h\u003e\n\nint fork(void)\n{\n\tfprintf(stderr, \u0022Sorry Windows doesn't support fork().\u005cn\u0022);\n\treturn 0;\n}\n#endif\n\n#include \u003clibwebsockets.h\u003e\n\n#include \u003cuv.h\u003e\n\n#if defined(LWS_HAVE_MALLOC_TRIM)\n#include \u003cmalloc.h\u003e\n#endif\n\nstatic struct lws_context *context;\nstatic lws_sorted_usec_list_t sul_lwsws;\nstatic char config_dir[128], default_plugin_path \u003d 1;\nstatic int opts \u003d 0, do_reload \u003d 1;\nstatic uv_loop_t loop;\nstatic uv_signal_t signal_outer[2];\nstatic int pids[32];\nvoid lwsl_emit_stderr(int level, const char *line);\n\n#define LWSWS_CONFIG_STRING_SIZE (64 * 1024)\n\nstatic const struct lws_extension exts[] \u003d {\n#if !defined(LWS_WITHOUT_EXTENSIONS)\n\t{\n\t\t\u0022permessage-deflate\u0022,\n\t\tlws_extension_callback_pm_deflate,\n\t\t\u0022permessage-deflate\u0022\n\t},\n#endif\n\t{ NULL, NULL, NULL /* terminator */ }\n};\n\n#if defined(LWS_WITH_PLUGINS)\nstatic const char * const plugin_dirs[] \u003d {\n\tINSTALL_DATADIR\u0022/libwebsockets-test-server/plugins/\u0022,\n\tNULL\n};\n#endif\n\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\nstatic struct option options[] \u003d {\n\t{ \u0022help\u0022,\tno_argument,\t\tNULL, 'h' },\n\t{ \u0022debug\u0022,\trequired_argument,\tNULL, 'd' },\n\t{ \u0022configdir\u0022, required_argument,\tNULL, 'c' },\n\t{ \u0022no-default-plugins\u0022, no_argument,\tNULL, 'n' },\n\t{ NULL, 0, 0, 0 }\n};\n#endif\n\nvoid signal_cb(uv_signal_t *watcher, int signum)\n{\n\tswitch (watcher-\u003esignum) {\n\tcase SIGTERM:\n\tcase SIGINT:\n\t\tbreak;\n\n\tcase SIGHUP:\n\t\tif (lws_context_is_deprecated(context))\n\t\t\treturn;\n\t\tlwsl_notice(\u0022Dropping listen sockets\u005cn\u0022);\n\t\tlws_context_deprecate(context, NULL);\n\t\treturn;\n\n\tdefault:\n\t\tsignal(SIGABRT, SIG_DFL);\n\t\tabort();\n\t\tbreak;\n\t}\n\tlwsl_err(\u0022Signal %d caught\u005cn\u0022, watcher-\u003esignum);\n\tuv_signal_stop(watcher);\n\tuv_signal_stop(\u0026signal_outer[1]);\n\tlws_context_destroy(context);\n}\n\nstatic void\nlwsws_min(lws_sorted_usec_list_t *sul)\n{\n\tlwsl_debug(\u0022%s\u005cn\u0022, __func__);\n\n#if defined(LWS_HAVE_MALLOC_TRIM)\n\tmalloc_trim(4 * 1024);\n#endif\n\n\tlws_sul_schedule(context, 0, \u0026sul_lwsws, lwsws_min, 60 * LWS_US_PER_SEC);\n}\n\nstatic int\ncontext_creation(void)\n{\n\tint cs_len \u003d LWSWS_CONFIG_STRING_SIZE - 1;\n\tstruct lws_context_creation_info info;\n\tchar *cs, *config_strings;\n\tvoid *foreign_loops[1];\n\n\tcs \u003d config_strings \u003d malloc(LWSWS_CONFIG_STRING_SIZE);\n\tif (!config_strings) {\n\t\tlwsl_err(\u0022Unable to allocate config strings heap\u005cn\u0022);\n\t\treturn -1;\n\t}\n\n\tmemset(\u0026info, 0, sizeof(info));\n\n\tinfo.external_baggage_free_on_destroy \u003d config_strings;\n\tinfo.pt_serv_buf_size \u003d 8192;\n\tinfo.options \u003d (uint64_t)((uint64_t)opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |\n\t\t\t LWS_SERVER_OPTION_EXPLICIT_VHOSTS |\n\t\t\t LWS_SERVER_OPTION_LIBUV);\n\n#if defined(LWS_WITH_PLUGINS)\n\tif (default_plugin_path)\n\t\tinfo.plugin_dirs \u003d plugin_dirs;\n#endif\n\tlwsl_notice(\u0022Using config dir: \u005c\u0022%s\u005c\u0022\u005cn\u0022, config_dir);\n\n\t/*\n\t * first go through the config for creating the outer context\n\t */\n\tif (lwsws_get_config_globals(\u0026info, config_dir, \u0026cs, \u0026cs_len))\n\t\tgoto init_failed;\n\n\tforeign_loops[0] \u003d \u0026loop;\n\tinfo.foreign_loops \u003d foreign_loops;\n\tinfo.pcontext \u003d \u0026context;\n\n\tcontext \u003d lws_create_context(\u0026info);\n\tif (context \u003d\u003d NULL) {\n\t\tlwsl_err(\u0022libwebsocket init failed\u005cn\u0022);\n\t\tgoto init_failed;\n\t}\n\n\t/*\n\t * then create the vhosts... protocols are entirely coming from\n\t * plugins, so we leave it NULL\n\t */\n\n\tinfo.extensions \u003d exts;\n\n\tif (lwsws_get_config_vhosts(context, \u0026info, config_dir, \u0026cs, \u0026cs_len))\n\t\treturn 1;\n\n\tlws_sul_schedule(context, 0, \u0026sul_lwsws, lwsws_min, 60 * LWS_US_PER_SEC);\n\n\treturn 0;\n\ninit_failed:\n\tfree(config_strings);\n\n\treturn 1;\n}\n\n\n/*\n * root-level sighup handler\n */\n\nstatic void\nreload_handler(int signum)\n{\n#ifndef _WIN32\n\tint m;\n\n\tswitch (signum) {\n\n\tcase SIGHUP: /* reload */\n\t\tfprintf(stderr, \u0022root process receives reload\u005cn\u0022);\n\t\tif (!do_reload) {\n\t\t\tfprintf(stderr, \u0022passing HUP to child processes\u005cn\u0022);\n\t\t\tfor (m \u003d 0; m \u003c (int)LWS_ARRAY_SIZE(pids); m++)\n\t\t\t\tif (pids[m])\n\t\t\t\t\tkill(pids[m], SIGHUP);\n\t\t\tsleep(1);\n\t\t}\n\t\tdo_reload \u003d 1;\n\t\tbreak;\n\tcase SIGINT:\n\tcase SIGTERM:\n\tcase SIGKILL:\n\t\tfprintf(stderr, \u0022parent process waiting 2s...\u005cn\u0022);\n\t\tsleep(2); /* give children a chance to deal with the signal */\n\t\tfprintf(stderr, \u0022killing service processes\u005cn\u0022);\n\t\tfor (m \u003d 0; m \u003c (int)LWS_ARRAY_SIZE(pids); m++)\n\t\t\tif (pids[m])\n\t\t\t\tkill(pids[m], SIGTERM);\n\t\texit(0);\n\t}\n#else\n\t// kill() implementation needed for WIN32\n#endif\n}\n\nint main(int argc, char **argv)\n{\n\tint n \u003d 0, budget \u003d 100, debug_level \u003d 1024 + 7;\n#ifndef _WIN32\n\tint m;\n\tint status;//, syslog_options \u003d LOG_PID | LOG_PERROR;\n#endif\n\n\tstrcpy(config_dir, \u0022/etc/lwsws\u0022);\n\twhile (n \u003e\u003d 0) {\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\n\t\tn \u003d getopt_long(argc, argv, \u0022hd:c:n\u0022, options, NULL);\n#else\n\t\tn \u003d getopt(argc, argv, \u0022hd:c:n\u0022);\n#endif\n\t\tif (n \u003c 0)\n\t\t\tcontinue;\n\t\tswitch (n) {\n\t\tcase 'd':\n\t\t\tdebug_level \u003d atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\tdefault_plugin_path \u003d 0;\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\tlws_strncpy(config_dir, optarg, sizeof(config_dir));\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\tfprintf(stderr, \u0022Usage: lwsws [-c \u003cconfig dir\u003e] \u0022\n\t\t\t\t\t\u0022[-d \u003clog bitfield\u003e] [--help] \u0022\n\t\t\t\t\t\u0022[-n]\u005cn\u0022);\n\t\t\texit(1);\n\t\t}\n\t}\n#ifndef _WIN32\n\t/*\n\t * We leave our original process up permanently, because that\n\t * suits systemd.\n\t *\n\t * Otherwise we get into problems when reload spawns new processes and\n\t * the original one dies randomly.\n\t */\n\n\tsignal(SIGHUP, reload_handler);\n\tsignal(SIGINT, reload_handler);\n\n\tfprintf(stderr, \u0022Root process is %u\u005cn\u0022, (unsigned int)getpid());\n\n\twhile (1) {\n\t\tif (do_reload) {\n\t\t\tdo_reload \u003d 0;\n\t\t\tn \u003d fork();\n\t\t\tif (n \u003d\u003d 0) /* new */\n\t\t\t\tbreak;\n\t\t\t/* old */\n\t\t\tif (n \u003e 0)\n\t\t\t\tfor (m \u003d 0; m \u003c (int)LWS_ARRAY_SIZE(pids); m++)\n\t\t\t\t\tif (!pids[m]) {\n\t\t\t\t\t\tpids[m] \u003d n;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t}\n#ifndef _WIN32\n\t\tsleep(2);\n\n\t\tn \u003d waitpid(-1, \u0026status, WNOHANG);\n\t\tif (n \u003e 0)\n\t\t\tfor (m \u003d 0; m \u003c (int)LWS_ARRAY_SIZE(pids); m++)\n\t\t\t\tif (pids[m] \u003d\u003d n) {\n\t\t\t\t\tpids[m] \u003d 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n#else\n// !!! implemenation needed\n#endif\n\t}\n#endif\n\t/* child process */\n\n\tlws_set_log_level(debug_level, lwsl_emit_stderr_notimestamp);\n\n\tlwsl_notice(\u0022lwsws libwebsockets web server - license CC0 + MIT\u005cn\u0022);\n\tlwsl_notice(\u0022(C) Copyright 2010-2020 Andy Green \u003candy@warmcat.com\u003e\u005cn\u0022);\n\n#if (UV_VERSION_MAJOR \u003e 0) // Travis...\n\tuv_loop_init(\u0026loop);\n#else\n\tfprintf(stderr, \u0022Your libuv is too old!\u005cn\u0022);\n\treturn 0;\n#endif\n\tuv_signal_init(\u0026loop, \u0026signal_outer[0]);\n\tuv_signal_start(\u0026signal_outer[0], signal_cb, SIGINT);\n\tuv_signal_init(\u0026loop, \u0026signal_outer[1]);\n\tuv_signal_start(\u0026signal_outer[1], signal_cb, SIGHUP);\n\n\tif (context_creation()) {\n\t\tlwsl_err(\u0022Context creation failed\u005cn\u0022);\n\t\treturn 1;\n\t}\n\n\tlws_service(context, 0);\n\n\tlwsl_err(\u0022%s: closing\u005cn\u0022, __func__);\n\n\tfor (n \u003d 0; n \u003c 2; n++) {\n\t\tuv_signal_stop(\u0026signal_outer[n]);\n\t\tuv_close((uv_handle_t *)\u0026signal_outer[n], NULL);\n\t}\n\n\t/* cancel the per-minute sul */\n\tlws_sul_cancel(\u0026sul_lwsws);\n\n\tlws_context_destroy(context);\n\t(void)budget;\n#if (UV_VERSION_MAJOR \u003e 0) // Travis...\n\twhile ((n \u003d uv_loop_close(\u0026loop)) \u0026\u0026 --budget)\n\t\tuv_run(\u0026loop, UV_RUN_ONCE);\n#endif\n\n\tfprintf(stderr, \u0022lwsws exited cleanly: %d\u005cn\u0022, n);\n\n#ifndef _WIN32\n\tcloselog();\n#endif\n\n\tcontext \u003d NULL;\n\n\treturn 0;\n}\n","s":{"c":1711689433,"u": 429}} ],"g": 2764,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}