]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/exit-status.c
man: fix typo and add link
[thirdparty/systemd.git] / src / shared / exit-status.c
CommitLineData
1afbdcb0
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
1afbdcb0
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
1afbdcb0 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
1afbdcb0
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdlib.h>
9a57c629 23#include <sys/wait.h>
1afbdcb0
LP
24
25#include "exit-status.h"
96342de6
LN
26#include "set.h"
27#include "macro.h"
1afbdcb0
LP
28
29const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
30
31 /* We cast to int here, so that -Wenum doesn't complain that
32 * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
33
34 switch ((int) status) {
35
36 case EXIT_SUCCESS:
37 return "SUCCESS";
38
39 case EXIT_FAILURE:
40 return "FAILURE";
41 }
42
43
44 if (level == EXIT_STATUS_SYSTEMD || level == EXIT_STATUS_LSB) {
45 switch ((int) status) {
46
47 case EXIT_CHDIR:
48 return "CHDIR";
49
50 case EXIT_NICE:
51 return "NICE";
52
53 case EXIT_FDS:
54 return "FDS";
55
56 case EXIT_EXEC:
57 return "EXEC";
58
59 case EXIT_MEMORY:
60 return "MEMORY";
61
62 case EXIT_LIMITS:
63 return "LIMITS";
64
65 case EXIT_OOM_ADJUST:
66 return "OOM_ADJUST";
67
68 case EXIT_SIGNAL_MASK:
69 return "SIGNAL_MASK";
70
71 case EXIT_STDIN:
72 return "STDIN";
73
74 case EXIT_STDOUT:
75 return "STDOUT";
76
77 case EXIT_CHROOT:
78 return "CHROOT";
79
80 case EXIT_IOPRIO:
81 return "IOPRIO";
82
83 case EXIT_TIMERSLACK:
84 return "TIMERSLACK";
85
86 case EXIT_SECUREBITS:
87 return "SECUREBITS";
88
89 case EXIT_SETSCHEDULER:
90 return "SETSCHEDULER";
91
92 case EXIT_CPUAFFINITY:
93 return "CPUAFFINITY";
94
95 case EXIT_GROUP:
96 return "GROUP";
97
98 case EXIT_USER:
99 return "USER";
100
101 case EXIT_CAPABILITIES:
102 return "CAPABILITIES";
103
104 case EXIT_CGROUP:
105 return "CGROUP";
106
107 case EXIT_SETSID:
108 return "SETSID";
109
110 case EXIT_CONFIRM:
111 return "CONFIRM";
112
113 case EXIT_STDERR:
114 return "STDERR";
115
1afbdcb0
LP
116 case EXIT_PAM:
117 return "PAM";
ff01d048
LP
118
119 case EXIT_NETWORK:
120 return "NETWORK";
4c2630eb
MS
121
122 case EXIT_NAMESPACE:
123 return "NAMESPACE";
8351ceae
LP
124
125 case EXIT_NO_NEW_PRIVILEGES:
126 return "NO_NEW_PRIVILEGES";
127
128 case EXIT_SECCOMP:
129 return "SECCOMP";
7b52a628
MS
130
131 case EXIT_SELINUX_CONTEXT:
132 return "SELINUX_CONTEXT";
ac45f971
LP
133
134 case EXIT_PERSONALITY:
135 return "PERSONALITY";
eef65bf3
MS
136
137 case EXIT_APPARMOR_PROFILE:
138 return "APPARMOR";
4298d0b5
LP
139
140 case EXIT_ADDRESS_FAMILIES:
141 return "ADDRESS_FAMILIES";
e66cf1a3
LP
142
143 case EXIT_RUNTIME_DIRECTORY:
144 return "RUNTIME_DIRECTORY";
3900e5fd
LP
145
146 case EXIT_CHOWN:
147 return "CHOWN";
a4152e3f
LP
148
149 case EXIT_MAKE_STARTER:
150 return "MAKE_STARTER";
060e088e
DM
151
152 case EXIT_BUS_ENDPOINT:
153 return "EXIT_BUS_ENDPOINT";
1afbdcb0
LP
154 }
155 }
156
157 if (level == EXIT_STATUS_LSB) {
158 switch ((int) status) {
159
160 case EXIT_INVALIDARGUMENT:
161 return "INVALIDARGUMENT";
162
163 case EXIT_NOTIMPLEMENTED:
164 return "NOTIMPLEMENTED";
165
166 case EXIT_NOPERMISSION:
167 return "NOPERMISSION";
168
169 case EXIT_NOTINSTALLED:
170 return "NOTINSSTALLED";
171
172 case EXIT_NOTCONFIGURED:
173 return "NOTCONFIGURED";
174
175 case EXIT_NOTRUNNING:
176 return "NOTRUNNING";
177 }
178 }
179
180 return NULL;
181}
9a57c629
LP
182
183
96342de6 184bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {
9a57c629
LP
185
186 if (code == CLD_EXITED)
96342de6
LN
187 return status == 0 ||
188 (success_status &&
3e2d435b 189 set_contains(success_status->status, INT_TO_PTR(status)));
9a57c629
LP
190
191 /* If a daemon does not implement handlers for some of the
192 * signals that's not considered an unclean shutdown */
193 if (code == CLD_KILLED)
194 return
195 status == SIGHUP ||
196 status == SIGINT ||
197 status == SIGTERM ||
96342de6
LN
198 status == SIGPIPE ||
199 (success_status &&
200 set_contains(success_status->signal, INT_TO_PTR(status)));
9a57c629
LP
201
202 return false;
203}
204
96342de6 205bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
9a57c629 206
96342de6 207 if (is_clean_exit(code, status, success_status))
9a57c629
LP
208 return true;
209
210 return
211 code == CLD_EXITED &&
212 (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
213}
37520c1b
LP
214
215void exit_status_set_free(ExitStatusSet *x) {
216 assert(x);
217
3e2d435b 218 set_free(x->status);
37520c1b 219 set_free(x->signal);
3e2d435b 220 x->status = x->signal = NULL;
37520c1b 221}
55ebf98c
LP
222
223bool exit_status_set_is_empty(ExitStatusSet *x) {
224 if (!x)
225 return true;
226
227 return set_isempty(x->status) && set_isempty(x->signal);
228}