1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "exit-status.h"
28 const char* exit_status_to_string(int status
, ExitStatusLevel level
) {
30 /* We cast to int here, so that -Wenum doesn't complain that
31 * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
42 if (IN_SET(level
, EXIT_STATUS_SYSTEMD
, EXIT_STATUS_LSB
)) {
66 case EXIT_SIGNAL_MASK
:
87 case EXIT_SETSCHEDULER
:
88 return "SETSCHEDULER";
90 case EXIT_CPUAFFINITY
:
99 case EXIT_CAPABILITIES
:
100 return "CAPABILITIES";
123 case EXIT_NO_NEW_PRIVILEGES
:
124 return "NO_NEW_PRIVILEGES";
129 case EXIT_SELINUX_CONTEXT
:
130 return "SELINUX_CONTEXT";
132 case EXIT_PERSONALITY
:
133 return "PERSONALITY";
135 case EXIT_APPARMOR_PROFILE
:
138 case EXIT_ADDRESS_FAMILIES
:
139 return "ADDRESS_FAMILIES";
141 case EXIT_RUNTIME_DIRECTORY
:
142 return "RUNTIME_DIRECTORY";
147 case EXIT_SMACK_PROCESS_LABEL
:
148 return "SMACK_PROCESS_LABEL";
153 case EXIT_STATE_DIRECTORY
:
154 return "STATE_DIRECTORY";
156 case EXIT_CACHE_DIRECTORY
:
157 return "CACHE_DIRECTORY";
159 case EXIT_LOGS_DIRECTORY
:
160 return "LOGS_DIRECTORY";
162 case EXIT_CONFIGURATION_DIRECTORY
:
163 return "CONFIGURATION_DIRECTORY";
167 if (level
== EXIT_STATUS_LSB
) {
170 case EXIT_INVALIDARGUMENT
:
171 return "INVALIDARGUMENT";
173 case EXIT_NOTIMPLEMENTED
:
174 return "NOTIMPLEMENTED";
176 case EXIT_NOPERMISSION
:
177 return "NOPERMISSION";
179 case EXIT_NOTINSTALLED
:
180 return "NOTINSTALLED";
182 case EXIT_NOTCONFIGURED
:
183 return "NOTCONFIGURED";
185 case EXIT_NOTRUNNING
:
193 bool is_clean_exit(int code
, int status
, ExitClean clean
, ExitStatusSet
*success_status
) {
195 if (code
== CLD_EXITED
)
196 return status
== 0 ||
198 set_contains(success_status
->status
, INT_TO_PTR(status
)));
200 /* If a daemon does not implement handlers for some of the signals that's not considered an unclean shutdown */
201 if (code
== CLD_KILLED
)
203 (clean
== EXIT_CLEAN_DAEMON
&& IN_SET(status
, SIGHUP
, SIGINT
, SIGTERM
, SIGPIPE
)) ||
205 set_contains(success_status
->signal
, INT_TO_PTR(status
)));
210 void exit_status_set_free(ExitStatusSet
*x
) {
213 x
->status
= set_free(x
->status
);
214 x
->signal
= set_free(x
->signal
);
217 bool exit_status_set_is_empty(ExitStatusSet
*x
) {
221 return set_isempty(x
->status
) && set_isempty(x
->signal
);
224 bool exit_status_set_test(ExitStatusSet
*x
, int code
, int status
) {
226 if (exit_status_set_is_empty(x
))
229 if (code
== CLD_EXITED
&& set_contains(x
->status
, INT_TO_PTR(status
)))
232 if (IN_SET(code
, CLD_KILLED
, CLD_DUMPED
) && set_contains(x
->signal
, INT_TO_PTR(status
)))