diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libmdsserver/macros.h | 10 | ||||
-rw-r--r-- | src/mds-base.c | 51 | ||||
-rw-r--r-- | src/mds-base.h | 12 | ||||
-rw-r--r-- | src/mds-clipboard.c | 3 | ||||
-rw-r--r-- | src/mds-echo.c | 3 | ||||
-rw-r--r-- | src/mds-kkbd.c | 3 | ||||
-rw-r--r-- | src/mds-registry/mds-registry.c | 3 | ||||
-rw-r--r-- | src/mds-respawn.c | 3 | ||||
-rw-r--r-- | src/mds-server/mds-server.c | 3 |
9 files changed, 82 insertions, 9 deletions
diff --git a/src/libmdsserver/macros.h b/src/libmdsserver/macros.h index 2d3f7a3..215c51a 100644 --- a/src/libmdsserver/macros.h +++ b/src/libmdsserver/macros.h @@ -24,6 +24,7 @@ #include <stdio.h> #include <errno.h> +#include <signal.h> /* #include <unistd.h> @@ -363,5 +364,14 @@ #define exit_if(CONDITION, INSTRUCTIONS) if (CONDITION) { INSTRUCTIONS return 1; } +/** + * The system is running out of memory. + * Quick, free up all your unused memory or kill yourself! + */ +#ifndef SIGDANGER +# define SIGDANGER SIGRTMAX +#endif + + #endif diff --git a/src/mds-base.c b/src/mds-base.c index be4efbb..429632e 100644 --- a/src/mds-base.c +++ b/src/mds-base.c @@ -192,8 +192,9 @@ int __attribute__((weak)) connect_to_display(void) */ static int server_initialised_fork_for_safety(void) { - unsigned pending_alarm = alarm(0); + unsigned pending_alarm = alarm(0); /* Disable the alarm. */ pid_t pid = fork(); + int status; if (pid == (pid_t)-1) { @@ -202,17 +203,29 @@ static int server_initialised_fork_for_safety(void) return -1; } else if (pid == 0) + /* Reinstate the alarm for the child. */ alarm(pending_alarm); else { - int status; + /* SIGDANGER cannot hurt the parent process. */ + if (xsigaction(SIGDANGER, SIG_IGN) < 0) + { + xperror(*argv); + eprint("WARNING! parent process failed to sig up ignoring of SIGDANGER."); + } + + /* Wait for the child process to die. */ if (uninterruptable_waitpid(pid, &status, 0) == (pid_t)-1) { xperror(*argv); kill(pid, SIGABRT); sleep(5); } + + /* Clean up after us. */ fork_cleanup(status); + + /* Die like the child. */ if (WIFEXITED(status)) exit(WEXITSTATUS(status)); else if (WIFSIGNALED(status)) raise(WTERMSIG(status)); exit(1); @@ -541,6 +554,32 @@ int main(int argc_, char** argv_) /** + * This function is called when `SIGDANGER` is received + * of `server_characteristics.danger_is_deadly` is non-zero + * unless the signal handler for `SIGDANGER` has been + * modified by the server implementation. + * + * This function will abruptly kill the process + * + * @param signo The signal that has been received + */ +static void commit_suicide(int signo) +{ + (void) signo; + + eprint("SIGDANGER received, process is killing itself to free memory."); + + /* abort(), but on the process rather than the thread. */ + xsigaction(SIGABRT, SIG_DFL); + kill(getpid(), SIGABRT); + + /* Just in case. */ + xperror(*argv); + _exit(1); +} + + +/** * Set up signal traps for all especially handled signals * * @return Non-zero on error @@ -556,9 +595,15 @@ int trap_signals(void) /* Implement clean exit on SIGINT. */ fail_if (xsigaction(SIGINT, received_terminate) < 0); - /* Implement clean exit on SIGRTMIN. */ + /* Implement silent interruption on SIGRTMIN. */ fail_if (xsigaction(SIGRTMIN, received_noop) < 0); + /* Implement silent interruption on SIGDANGER. */ + if (server_characteristics.danger_is_deadly) + { fail_if (xsigaction(SIGDANGER, commit_suicide) < 0); } + else + { fail_if (xsigaction(SIGDANGER, SIG_IGN) < 0); } + return 0; pfail: xperror(*argv); diff --git a/src/mds-base.h b/src/mds-base.h index 2dac449..c3c6c9c 100644 --- a/src/mds-base.h +++ b/src/mds-base.h @@ -64,6 +64,18 @@ typedef struct server_characteristics */ unsigned fork_for_safety : 1; + /** + * Seting this to non-zero without setting a signal action + * for `SIGDANGER` will cause the server to die if `SIGDANGER` + * is received. It is safe to set both `danger_is_deadly` and + * `fork_for_safety` to non-zero, during the call of + * `server_initialised` the signal handler for `SIGDANGER` + * in the parent process will be set to `SIG_IGN` independently + * of the value of `danger_is_deadly` if `fork_for_safety` + * is set to non-zero. + */ + unsigned danger_is_deadly : 1; + } __attribute__((packed)) server_characteristics_t; diff --git a/src/mds-clipboard.c b/src/mds-clipboard.c index 7ed2508..6ad068b 100644 --- a/src/mds-clipboard.c +++ b/src/mds-clipboard.c @@ -46,7 +46,8 @@ server_characteristics_t server_characteristics = .require_display = 1, .require_respawn_info = 1, .sanity_check_argc = 1, - .fork_for_safety = 0 + .fork_for_safety = 0, + .danger_is_deadly = 0 }; diff --git a/src/mds-echo.c b/src/mds-echo.c index 01f8e97..2b20387 100644 --- a/src/mds-echo.c +++ b/src/mds-echo.c @@ -46,7 +46,8 @@ server_characteristics_t server_characteristics = .require_display = 1, .require_respawn_info = 0, .sanity_check_argc = 1, - .fork_for_safety = 0 + .fork_for_safety = 0, + .danger_is_deadly = 0 }; diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c index 11d33b1..db12746 100644 --- a/src/mds-kkbd.c +++ b/src/mds-kkbd.c @@ -88,7 +88,8 @@ server_characteristics_t server_characteristics = .require_display = 1, .require_respawn_info = 0, .sanity_check_argc = 1, - .fork_for_safety = 1 + .fork_for_safety = 1, + .danger_is_deadly = 0 }; diff --git a/src/mds-registry/mds-registry.c b/src/mds-registry/mds-registry.c index baefee7..1676cf6 100644 --- a/src/mds-registry/mds-registry.c +++ b/src/mds-registry/mds-registry.c @@ -43,7 +43,8 @@ server_characteristics_t server_characteristics = .require_display = 1, .require_respawn_info = 0, .sanity_check_argc = 1, - .fork_for_safety = 0 + .fork_for_safety = 0, + .danger_is_deadly = 0 }; diff --git a/src/mds-respawn.c b/src/mds-respawn.c index 02b466c..6072ad9 100644 --- a/src/mds-respawn.c +++ b/src/mds-respawn.c @@ -47,7 +47,8 @@ server_characteristics_t server_characteristics = .require_display = 0, .require_respawn_info = 1, .sanity_check_argc = 0, - .fork_for_safety = 0 + .fork_for_safety = 0, + .danger_is_deadly = 0 }; diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index 85e7c5c..a77fadb 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -57,7 +57,8 @@ server_characteristics_t server_characteristics = .require_display = 0, /* We will service one ourself. */ .require_respawn_info = 1, .sanity_check_argc = 1, - .fork_for_safety = 0 + .fork_for_safety = 0, + .danger_is_deadly = 0 }; |