diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-08-11 05:47:10 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-08-11 05:47:10 +0200 |
commit | 4f8ac368dbead32aaa30684c29df3afa0a8ba17f (patch) | |
tree | 60a1007dba7a0f2456c44f7152e68b274f4bb3f2 /src/mds-base.c | |
parent | m (diff) | |
download | mds-4f8ac368dbead32aaa30684c29df3afa0a8ba17f.tar.gz mds-4f8ac368dbead32aaa30684c29df3afa0a8ba17f.tar.bz2 mds-4f8ac368dbead32aaa30684c29df3afa0a8ba17f.tar.xz |
add fork_for_safety option + beginning of kernel-based keyboard
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
-rw-r--r-- | src/mds-base.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/src/mds-base.c b/src/mds-base.c index 77b8835..1bae36b 100644 --- a/src/mds-base.c +++ b/src/mds-base.c @@ -182,12 +182,54 @@ int __attribute__((weak)) connect_to_display(void) return 1; } + +/** + * Put the server into a fork of itself as + * described by the `fork_for_safety` + * server characteristics + * + * @return Zero on success, -1 on error + */ +static int server_initialised_fork_for_safety(void) +{ + unsigned pending_alarm = alarm(0); + pid_t pid = fork(); + + if (pid == (pid_t)-1) + { + xperror(*argv); + eprint("while forking for safety."); + return -1; + } + else if (pid == 0) + alarm(pending_alarm); + else + { + int status; + if (uninterruptable_waitpid(pid, &status, 0) == (pid_t)-1) + { + xperror(*argv); + kill(pid, SIGABRT); + sleep(5); + } + fork_cleanup(status); + if (WIFEXITED(status)) exit(WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) raise(WTERMSIG(status)); + exit(1); + } + + return 0; +} + + /** * This function should be called when the server has * been properly initialised but before initialisation * of anything that is removed at forking is initialised + * + * @return Zero on success, -1 on error */ -void __attribute__((weak)) server_initialised(void) +int __attribute__((weak)) server_initialised(void) { pid_t r; if (on_init_fork && (r = fork())) @@ -196,7 +238,7 @@ void __attribute__((weak)) server_initialised(void) { xperror(*argv); eprint("while forking at completed initialisation."); - exit(1); + return -1; } else exit(0); @@ -204,6 +246,10 @@ void __attribute__((weak)) server_initialised(void) if (on_init_sh != NULL) system(on_init_sh); + + if (server_characteristics.fork_for_safety) + return server_initialised_fork_for_safety(); + return 0; } @@ -495,5 +541,23 @@ int trap_signals(void) } +/** + * This function should be implemented by the actual server implementation + * if the server has set `server_characteristics.fork_for_safety` to be + * true + * + * This function is called by the parent server process when the + * child server process exits, if the server has completed its + * initialisation + * + * @param status The status the child died with + */ +void __attribute__((weak)) fork_cleanup(int status) +{ + (void) status; + fprintf(stderr, "Something is wrong, `fork_cleanup` has been called but not reimplemented."); +} + + #undef try |