chiark / gitweb /
systemctl: conform to LSB with the "status" return code
[elogind.git] / src / systemctl / systemctl.c
index 8d496ab709c99f50310cab5d46b2328692700daa..24543ee06db3d6e0dcd1112d14a582e0a28b6917 100644 (file)
@@ -2658,6 +2658,7 @@ typedef struct UnitStatusInfo {
         pid_t main_pid;
         pid_t control_pid;
         const char *status_text;
+        const char *pid_file;
         bool running:1;
 
         usec_t start_timestamp;
@@ -3057,6 +3058,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
                                 i->default_control_group = s;
                         else if (streq(name, "StatusText"))
                                 i->status_text = s;
+                        else if (streq(name, "PIDFile"))
+                                i->pid_file = s;
                         else if (streq(name, "SysFSPath"))
                                 i->sysfs_path = s;
                         else if (streq(name, "Where"))
@@ -3547,9 +3550,19 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
 
         if (!streq_ptr(info.active_state, "active") &&
             !streq_ptr(info.active_state, "reloading") &&
-            streq(verb, "status"))
+            streq(verb, "status")) {
                 /* According to LSB: "program not running" */
-                r = 3;
+                /* 0: program is running or service is OK
+                 * 1: program is dead and /var/run pid file exists
+                 * 2: program is dead and /var/lock lock file exists
+                 * 3: program is not running
+                 * 4: program or service status is unknown
+                 */
+                if (info.pid_file && access(info.pid_file, F_OK) == 0)
+                        r = 1;
+                else
+                        r = 3;
+       }
 
         while ((p = info.exec)) {
                 LIST_REMOVE(ExecStatusInfo, exec, info.exec, p);
@@ -4872,7 +4885,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:i", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:Pn:o:i", options, NULL)) >= 0) {
 
                 switch (c) {