aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-08-20 20:59:35 +0200
committerMattias Andrée <maandree@operamail.com>2014-08-20 20:59:35 +0200
commit1c49207227eecbf2e9b96b04833e5554bf9589b9 (patch)
treedac7042795c7574d3967e55c8ff719b2a5572125 /src
parenttypo (diff)
downloadmds-1c49207227eecbf2e9b96b04833e5554bf9589b9.tar.gz
mds-1c49207227eecbf2e9b96b04833e5554bf9589b9.tar.bz2
mds-1c49207227eecbf2e9b96b04833e5554bf9589b9.tar.xz
add sigdanger support
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
-rw-r--r--src/libmdsserver/macros.h10
-rw-r--r--src/mds-base.c51
-rw-r--r--src/mds-base.h12
-rw-r--r--src/mds-clipboard.c3
-rw-r--r--src/mds-echo.c3
-rw-r--r--src/mds-kkbd.c3
-rw-r--r--src/mds-registry/mds-registry.c3
-rw-r--r--src/mds-respawn.c3
-rw-r--r--src/mds-server/mds-server.c3
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
};