summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-04-23 19:26:25 +0200
committerLennart Poettering <lennart@poettering.net>2018-04-27 17:32:01 +0200
commit0a233ba1795fc526e8b604da9893ee3e3a6702c3 (patch)
tree62e5f14b9ecfe50fb83dad0961a0a45ab6212110
parent3e0bff7d0b812357c43aa831c57a34f00cdf2f31 (diff)
downloadsystemd-0a233ba1795fc526e8b604da9893ee3e3a6702c3.tar.gz
exit-status: list BSD exit codes too
Let's optionally translate BSD exit codes to error strings too. My first approach on adding this was to turn ExitStatusLevel into a bitmask rather than a linear level, with one bit for the various feature bits. However, the exit code ranges are generally not defined independently from each other, i.e. our own ones are defined with the LSB ones in mind, and most sets are defined with the ISO C ones. Hence, instead I changed the existing hierarchy of MINIMAL, SYSTEMD, LSB with an alias of FULL == LSB, only slightly by seperating FULL and LSB into two separate levels, so that there's now: 1. MINIMAL (only EXIT_SUCCESS/EXIT_FAILURE) 2. SYSTEMD (incorporating our own exit codes) 3. LSB (like SYSTEMD but adding in LSB service exit codes) 4. FULL (like FULL but adding BSD exit codes) Note that across the codebase only FULL, SYSTEMD, and MINIMAL are used, depending on context, how much we know about the process and whether we are logging for debugging purposes or not. This means the LSB level wouldn't really have to be separate, but it appeared careless to me to fold it into FULL along with the BSD exit codes. Note that this commit doesn't change much for regular codepaths: the FULL exit status level is only used during debug logging, as a helper to the user reading the debug logs.
-rw-r--r--src/basic/exit-status.c78
-rw-r--r--src/basic/exit-status.h8
2 files changed, 74 insertions, 12 deletions
diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c
index 3827f254fa..c2064b7ef1 100644
--- a/src/basic/exit-status.c
+++ b/src/basic/exit-status.c
@@ -7,6 +7,7 @@
#include <signal.h>
#include <stdlib.h>
+#include <sysexits.h>
#include "exit-status.h"
#include "macro.h"
@@ -14,10 +15,21 @@
const char* exit_status_to_string(int status, ExitStatusLevel level) {
- /* We cast to int here, so that -Wenum doesn't complain that
- * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
-
- switch (status) {
+ /* Exit status ranges:
+ *
+ * 0…1 │ ISO C, EXIT_SUCCESS + EXIT_FAILURE
+ * 2…7 │ LSB exit codes for init scripts
+ * 8…63 │ (Currently unmapped)
+ * 64…78 │ BSD defined exit codes
+ * 79…199 │ (Currently unmapped)
+ * 200…241 │ systemd's private error codes (might be extended to 254 in future development)
+ * 242…254 │ (Currently unmapped, but see above)
+ * 255 │ (We should probably stay away from that one, it's frequently used by applications to indicate an
+ * │ exit reason that cannot really be expressed in a single exit status value — such as a propagated
+ * │ signal or such)
+ */
+
+ switch (status) { /* We always cover the ISO C ones */
case EXIT_SUCCESS:
return "SUCCESS";
@@ -26,8 +38,8 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
return "FAILURE";
}
- if (IN_SET(level, EXIT_STATUS_SYSTEMD, EXIT_STATUS_LSB)) {
- switch (status) {
+ if (IN_SET(level, EXIT_STATUS_SYSTEMD, EXIT_STATUS_LSB, EXIT_STATUS_FULL)) {
+ switch (status) { /* Optionally we cover our own ones */
case EXIT_CHDIR:
return "CHDIR";
@@ -151,8 +163,8 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
}
}
- if (level == EXIT_STATUS_LSB) {
- switch (status) {
+ if (IN_SET(level, EXIT_STATUS_LSB, EXIT_STATUS_FULL)) {
+ switch (status) { /* Optionally we support LSB ones */
case EXIT_INVALIDARGUMENT:
return "INVALIDARGUMENT";
@@ -174,6 +186,56 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
}
}
+ if (level == EXIT_STATUS_FULL) {
+ switch (status) { /* Optionally, we support BSD exit statusses */
+
+ case EX_USAGE:
+ return "USAGE";
+
+ case EX_DATAERR:
+ return "DATAERR";
+
+ case EX_NOINPUT:
+ return "NOINPUT";
+
+ case EX_NOUSER:
+ return "NOUSER";
+
+ case EX_NOHOST:
+ return "NOHOST";
+
+ case EX_UNAVAILABLE:
+ return "UNAVAILABLE";
+
+ case EX_SOFTWARE:
+ return "SOFTWARE";
+
+ case EX_OSERR:
+ return "OSERR";
+
+ case EX_OSFILE:
+ return "OSFILE";
+
+ case EX_CANTCREAT:
+ return "CANTCREAT";
+
+ case EX_IOERR:
+ return "IOERR";
+
+ case EX_TEMPFAIL:
+ return "TEMPFAIL";
+
+ case EX_PROTOCOL:
+ return "PROTOCOL";
+
+ case EX_NOPERM:
+ return "NOPERM";
+
+ case EX_CONFIG:
+ return "CONFIG";
+ }
+ }
+
return NULL;
}
diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h
index 28a427bc98..9686e31e06 100644
--- a/src/basic/exit-status.h
+++ b/src/basic/exit-status.h
@@ -29,10 +29,10 @@ enum {
EXIT_NOTCONFIGURED = 6,
EXIT_NOTRUNNING = 7,
- /* The LSB suggests that error codes >= 200 are "reserved". We
- * use them here under the assumption that they hence are
- * unused by init scripts. */
+ /* BSD's sysexits.h defines a couple EX_xyz exit codes in the range 64 … 78 */
+ /* The LSB suggests that error codes >= 200 are "reserved". We use them here under the assumption that they
+ * hence are unused by init scripts. */
EXIT_CHDIR = 200,
EXIT_NICE,
EXIT_FDS,
@@ -81,7 +81,7 @@ typedef enum ExitStatusLevel {
EXIT_STATUS_MINIMAL, /* only cover libc EXIT_STATUS/EXIT_FAILURE */
EXIT_STATUS_SYSTEMD, /* cover libc and systemd's own exit codes */
EXIT_STATUS_LSB, /* cover libc, systemd's own and LSB exit codes */
- EXIT_STATUS_FULL = EXIT_STATUS_LSB
+ EXIT_STATUS_FULL, /* cover libc, systemd's own, LSB and BSD (EX_xyz) exit codes */
} ExitStatusLevel;
typedef struct ExitStatusSet {