service: consider a process exiting with SIGTERM a clean exit
authorLennart Poettering <lennart@poettering.net>
Sun, 16 May 2010 01:55:19 +0000 (03:55 +0200)
committerLennart Poettering <lennart@poettering.net>
Sun, 16 May 2010 01:55:19 +0000 (03:55 +0200)
mount.c
service.c
socket.c
util.c
util.h

diff --git a/mount.c b/mount.c
index 2b24ea5..ec03a52 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -900,7 +900,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         assert(m);
         assert(pid >= 0);
 
-        success = code == CLD_EXITED && status == 0;
+        success = is_clean_exit(code, status);
         m->failure = m->failure || !success;
 
         assert(m->control_pid == pid);
index ca25248..bf91561 100644 (file)
--- a/service.c
+++ b/service.c
@@ -1890,7 +1890,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         assert(s);
         assert(pid >= 0);
 
-        success = code == CLD_EXITED && status == 0;
+        success = is_clean_exit(code, status);
         s->failure = s->failure || !success;
 
         if (s->main_pid == pid) {
index aafe439..259f273 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -1204,7 +1204,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         assert(s);
         assert(pid >= 0);
 
-        success = code == CLD_EXITED && status == 0;
+        success = is_clean_exit(code, status);
         s->failure = s->failure || !success;
 
         assert(s->control_pid == pid);
diff --git a/util.c b/util.c
index 95791f9..5e3654d 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1910,6 +1910,23 @@ int make_stdio(int fd) {
         return 0;
 }
 
+bool is_clean_exit(int code, int status) {
+
+        if (code == CLD_EXITED)
+                return status == 0;
+
+        /* If a daemon does not implement handlers for some of the
+         * signals that's not considered an unclean shutdown */
+        if (code == CLD_KILLED)
+                return
+                        status == SIGHUP ||
+                        status == SIGINT ||
+                        status == SIGTERM ||
+                        status == SIGPIPE;
+
+        return false;
+}
+
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
         [IOPRIO_CLASS_RT] = "realtime",
diff --git a/util.h b/util.h
index ba27c75..d0fc319 100644 (file)
--- a/util.h
+++ b/util.h
@@ -181,6 +181,8 @@ char *format_timestamp(char *buf, size_t l, usec_t t);
 
 int make_stdio(int fd);
 
+bool is_clean_exit(int code, int status);
+
 #define DEFINE_STRING_TABLE_LOOKUP(name,type)                           \
         const char *name##_to_string(type i) {                          \
                 if (i < 0 || i >= (type) ELEMENTSOF(name##_table))      \