2010-08-20 05:26:37 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-08-20 05:26:37 +04:00
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-08-20 05:26:37 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-08-20 05:26:37 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <stdlib.h>
2011-01-20 20:22:03 +03:00
# include <sys/wait.h>
2010-08-20 05:26:37 +04:00
# include "exit-status.h"
2012-08-13 15:58:01 +04:00
# include "set.h"
# include "macro.h"
2010-08-20 05:26:37 +04:00
const char * exit_status_to_string ( ExitStatus 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 ( ( int ) status ) {
case EXIT_SUCCESS :
return " SUCCESS " ;
case EXIT_FAILURE :
return " FAILURE " ;
}
if ( level = = EXIT_STATUS_SYSTEMD | | level = = EXIT_STATUS_LSB ) {
switch ( ( int ) status ) {
case EXIT_CHDIR :
return " CHDIR " ;
case EXIT_NICE :
return " NICE " ;
case EXIT_FDS :
return " FDS " ;
case EXIT_EXEC :
return " EXEC " ;
case EXIT_MEMORY :
return " MEMORY " ;
case EXIT_LIMITS :
return " LIMITS " ;
case EXIT_OOM_ADJUST :
return " OOM_ADJUST " ;
case EXIT_SIGNAL_MASK :
return " SIGNAL_MASK " ;
case EXIT_STDIN :
return " STDIN " ;
case EXIT_STDOUT :
return " STDOUT " ;
case EXIT_CHROOT :
return " CHROOT " ;
case EXIT_IOPRIO :
return " IOPRIO " ;
case EXIT_TIMERSLACK :
return " TIMERSLACK " ;
case EXIT_SECUREBITS :
return " SECUREBITS " ;
case EXIT_SETSCHEDULER :
return " SETSCHEDULER " ;
case EXIT_CPUAFFINITY :
return " CPUAFFINITY " ;
case EXIT_GROUP :
return " GROUP " ;
case EXIT_USER :
return " USER " ;
case EXIT_CAPABILITIES :
return " CAPABILITIES " ;
case EXIT_CGROUP :
return " CGROUP " ;
case EXIT_SETSID :
return " SETSID " ;
case EXIT_CONFIRM :
return " CONFIRM " ;
case EXIT_STDERR :
return " STDERR " ;
case EXIT_PAM :
return " PAM " ;
2011-08-02 07:24:58 +04:00
case EXIT_NETWORK :
return " NETWORK " ;
2011-11-17 03:21:16 +04:00
case EXIT_NAMESPACE :
return " NAMESPACE " ;
2012-07-17 06:17:53 +04:00
case EXIT_NO_NEW_PRIVILEGES :
return " NO_NEW_PRIVILEGES " ;
case EXIT_SECCOMP :
return " SECCOMP " ;
2014-02-06 13:05:16 +04:00
case EXIT_SELINUX_CONTEXT :
return " SELINUX_CONTEXT " ;
2014-02-19 05:15:24 +04:00
case EXIT_PERSONALITY :
return " PERSONALITY " ;
2014-02-20 19:19:44 +04:00
case EXIT_APPARMOR_PROFILE :
return " APPARMOR " ;
2014-02-25 23:37:03 +04:00
case EXIT_ADDRESS_FAMILIES :
return " ADDRESS_FAMILIES " ;
2014-03-03 20:14:07 +04:00
case EXIT_RUNTIME_DIRECTORY :
return " RUNTIME_DIRECTORY " ;
2014-06-05 11:55:53 +04:00
case EXIT_CHOWN :
return " CHOWN " ;
2014-06-05 14:24:03 +04:00
case EXIT_MAKE_STARTER :
return " MAKE_STARTER " ;
2010-08-20 05:26:37 +04:00
}
}
if ( level = = EXIT_STATUS_LSB ) {
switch ( ( int ) status ) {
case EXIT_INVALIDARGUMENT :
return " INVALIDARGUMENT " ;
case EXIT_NOTIMPLEMENTED :
return " NOTIMPLEMENTED " ;
case EXIT_NOPERMISSION :
return " NOPERMISSION " ;
case EXIT_NOTINSTALLED :
return " NOTINSSTALLED " ;
case EXIT_NOTCONFIGURED :
return " NOTCONFIGURED " ;
case EXIT_NOTRUNNING :
return " NOTRUNNING " ;
}
}
return NULL ;
}
2011-01-20 20:22:03 +03:00
2012-08-13 15:58:01 +04:00
bool is_clean_exit ( int code , int status , ExitStatusSet * success_status ) {
2011-01-20 20:22:03 +03:00
if ( code = = CLD_EXITED )
2012-08-13 15:58:01 +04:00
return status = = 0 | |
( success_status & &
set_contains ( success_status - > code , INT_TO_PTR ( status ) ) ) ;
2011-01-20 20:22:03 +03:00
/* 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 | |
2012-08-13 15:58:01 +04:00
status = = SIGPIPE | |
( success_status & &
set_contains ( success_status - > signal , INT_TO_PTR ( status ) ) ) ;
2011-01-20 20:22:03 +03:00
return false ;
}
2012-08-13 15:58:01 +04:00
bool is_clean_exit_lsb ( int code , int status , ExitStatusSet * success_status ) {
2011-01-20 20:22:03 +03:00
2012-08-13 15:58:01 +04:00
if ( is_clean_exit ( code , status , success_status ) )
2011-01-20 20:22:03 +03:00
return true ;
return
code = = CLD_EXITED & &
( status = = EXIT_NOTINSTALLED | | status = = EXIT_NOTCONFIGURED ) ;
}
2014-07-03 14:47:40 +04:00
void exit_status_set_free ( ExitStatusSet * x ) {
assert ( x ) ;
set_free ( x - > code ) ;
set_free ( x - > signal ) ;
x - > code = x - > signal = NULL ;
}