summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2020-11-26 15:19:21 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2023-05-03 23:11:34 -0400
commite4a1c4fa737df693b83ffdb16396ffec13dc2c2a (patch)
tree26298c672e411f89e431c7376577717194b1f286 /src
parent007843439a2654dd6dd5de9b6412f7fc5b9e2b22 (diff)
downloadlighttpd-git-e4a1c4fa737df693b83ffdb16396ffec13dc2c2a.tar.gz
[core] _WIN32 signal-related compat
Note: behavior under bash.exe might be different than under cmd.exe
Diffstat (limited to 'src')
-rw-r--r--src/gw_backend.c4
-rw-r--r--src/lighttpd-angel.c11
-rw-r--r--src/mod_cgi.c25
-rw-r--r--src/server.c66
4 files changed, 101 insertions, 5 deletions
diff --git a/src/gw_backend.c b/src/gw_backend.c
index 2b4f13af..c5b0ddda 100644
--- a/src/gw_backend.c
+++ b/src/gw_backend.c
@@ -27,6 +27,10 @@
#include <string.h>
#include <unistd.h>
+#ifndef SIGKILL
+#define SIGKILL 9
+#endif
+
#include "base.h"
#include "algo_md.h"
#include "array.h"
diff --git a/src/lighttpd-angel.c b/src/lighttpd-angel.c
index 6452746c..599bbfc7 100644
--- a/src/lighttpd-angel.c
+++ b/src/lighttpd-angel.c
@@ -11,6 +11,15 @@
* it has to stay safe and small to be trustable
*/
+#ifdef _WIN32
+#include <stdio.h>
+int main (void) {
+ fprintf(stderr, "lighttpd-angel is not implemented on Windows. "
+ "Prefer using Windows services.\n");
+ return 1;
+}
+#else /* ! _WIN32 */
+
#include <sys/wait.h>
#include <stdio.h>
@@ -104,3 +113,5 @@ int main (int argc, char **argv)
return 0;
}
+
+#endif /* ! _WIN32 */
diff --git a/src/mod_cgi.c b/src/mod_cgi.c
index 0b2a9c9b..17561231 100644
--- a/src/mod_cgi.c
+++ b/src/mod_cgi.c
@@ -208,26 +208,47 @@ __attribute_cold__
__attribute_pure__
static int mod_cgi_str_to_signal (const char *s, int default_sig) {
static const struct { const char *name; int sig; } sigs[] = {
- { "HUP", SIGHUP }
- ,{ "INT", SIGINT }
+ #ifdef SIGHUP
+ { "HUP", SIGHUP },
+ #endif
+ { "INT", SIGINT }
+ #ifdef SIGQUIT
,{ "QUIT", SIGQUIT }
+ #endif
+ #ifdef SIGILL
,{ "ILL", SIGILL }
+ #endif
+ #ifdef SIGTRAP
,{ "TRAP", SIGTRAP }
+ #endif
+ #ifdef SIGABRT
,{ "ABRT", SIGABRT }
+ #endif
#ifdef SIGBUS
,{ "BUS", SIGBUS }
#endif
+ #ifdef SIGFPE
,{ "FPE", SIGFPE }
+ #endif
+ #ifndef SIGKILL
+ #define SIGKILL 9
+ #endif
,{ "KILL", SIGKILL }
#ifdef SIGUSR1
,{ "USR1", SIGUSR1 }
#endif
+ #ifdef SIGSEGV
,{ "SEGV", SIGSEGV }
+ #endif
#ifdef SIGUSR2
,{ "USR2", SIGUSR2 }
#endif
+ #ifdef SIGPIPE
,{ "PIPE", SIGPIPE }
+ #endif
+ #ifdef SIGALRM
,{ "ALRM", SIGALRM }
+ #endif
,{ "TERM", SIGTERM }
#ifdef SIGCHLD
,{ "CHLD", SIGCHLD }
diff --git a/src/server.c b/src/server.c
index bd47c864..d6a37cbc 100644
--- a/src/server.c
+++ b/src/server.c
@@ -135,6 +135,16 @@ static volatile sig_atomic_t handle_sig_alarm = 1;
static volatile sig_atomic_t handle_sig_hup = 0;
static int idle_limit = 0;
+#ifdef _WIN32
+#ifndef SIGBREAK
+#define SIGBREAK 21
+#endif
+/* Ctrl-BREAK (repurposed and treated as SIGUSR1)*/
+#ifndef SIGUSR1
+#define SIGUSR1 SIGBREAK
+#endif
+#endif
+
#if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
static volatile siginfo_t last_sigterm_info;
static volatile siginfo_t last_sighup_info;
@@ -201,13 +211,56 @@ static void signal_handler(int sig) {
graceful_shutdown = 1;
}
break;
+ #ifndef _WIN32
case SIGALRM: handle_sig_alarm = 1; break;
case SIGHUP: handle_sig_hup = 1; break;
case SIGCHLD: handle_sig_child = 1; break;
+ #endif
}
}
#endif
+#if defined(HAVE_SIGNAL)
+#ifdef _WIN32
+static BOOL WINAPI ConsoleCtrlHandler(DWORD dwType)
+{
+ /* Note: Windows handles "signals" inconsistently, varying depending on
+ * whether or not the program is attached to a non-hidden window.
+ * CTRL_CLOSE_EVENT sent by taskkill can be received if attached to a
+ * non-hidden window, but taskkill /f must be used (and CTRL_CLOSE_EVENT
+ * is not received here) if process is not attached to a window, or if
+ * the window is hidden. (WTH MS?!) This *does not* catch CTRL_CLOSE_EVENT:
+ * start -FilePath .\lighttpd.exe -ArgumentList "-D -f lighttpd.conf"
+ * -WindowStyle Hidden # (or None)
+ * but any other -WindowStyle can catch CTRL_CLOSE_EVENT.
+ * CTRL_C_EVENT can only be sent to 0 (self process group) or self pid
+ * and is ignored by default (sending signal does not indicate failure)
+ * in numerous other cases. Some people have resorted to standalone helper
+ * programs to attempt AttachConsole() to a target pid before sending
+ * CTRL_C_EVENT via GenerateConsoleCtrlEvent(). Another alternative is
+ * running lighttpd as a Windows service, which uses a different mechanism,
+ * also more limited than unix signals. Other alternatives include
+ * NSSM (Non-Sucking Service Manager) or cygwin's cygrunsrv program */
+ switch(dwType) {
+ case CTRL_C_EVENT:
+ signal_handler(SIGINT);
+ break;
+ case CTRL_BREAK_EVENT:
+ /* Ctrl-BREAK (repurposed and treated as SIGUSR1)*/
+ signal_handler(SIGUSR1);
+ break;
+ case CTRL_CLOSE_EVENT:/* sent by taskkill */
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* non-cancellable event; program terminates soon after return */
+ signal_handler(SIGTERM);/* trigger server shutdown in main thread */
+ Sleep(2000); /* sleep 2 secs to give threads chance to exit*/
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+#endif
static void server_main_setup_signals (void) {
#ifdef HAVE_SIGACTION
@@ -246,21 +299,28 @@ static void server_main_setup_signals (void) {
act.sa_flags |= SA_RESTART | SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, NULL);
#elif defined(HAVE_SIGNAL)
+ #ifndef _WIN32
/* ignore the SIGPIPE from sendfile() */
signal(SIGPIPE, SIG_IGN);
- signal(SIGALRM, signal_handler);
+ #endif
+ signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
+ #ifndef _WIN32
signal(SIGHUP, signal_handler);
+ signal(SIGALRM, signal_handler);
+ signal(SIGUSR1, signal_handler);
signal(SIGCHLD, signal_handler);
- signal(SIGINT, signal_handler);
+ #else
+ /* Ctrl-BREAK (repurposed and treated as SIGUSR1)*/
signal(SIGUSR1, signal_handler);
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleCtrlHandler,TRUE);
+ #endif
#ifndef _MSC_VER
signal(SIGBUS, sys_setjmp_sigbus);
#endif
#endif
}
-
#ifdef HAVE_FORK
static int daemonize(void) {
int pipefd[2];