# ------------------------------------------------------------------------------ # Error management functions # This file is part of the init.sh project # Copyright (c) 2019-2021 Geoffray Levasseur # ------------------------------------------------------------------------------ # This file is distributed under 3-clause BSD license. # The complete license agreement can be obtained at: # https://opensource.org/licenses/BSD-3-Clause # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Exit with error function die() { local errorcode=$1 # Don't trigger the ERR signal as we already managed the error trap - ERR if [[ "$KEEPGOING" != "true" ]] || [[ "$2" == "--force" ]]; then prnt E "Premature exit with error (code #$errorcode)." # We remove KEEPGOING in case of --force so error() behave correctly export KEEPGOING=false exit $errorcode else prnt W "Continuing despite error #$errorcode." fi unset errorcode # Put the trigger back (only executed with --keepgoing) trap "error ${LINENO}" ERR } export -f die # ------------------------------------------------------------------------------ # Function trigered on Ctrl+C pressed or external kill affecting us function terminate() { prnt E "$1 recieved, exiting at once." die 128 --force } trap "terminate 'Ctrl + C'" SIGINT trap "terminate 'SIGTERM'" SIGTERM # ------------------------------------------------------------------------------ # Function triggered on error function error() { local parent_lineno="$1" local message="$2" local code="${3:-1}" # Print error header prnt E "${BIWhite}*** ${BIRed}A fatal error occured, the script will stop now!$DEFAULTCOL" if [[ -n "$message" ]]; then prnt E "Error line $parent_lineno, code $code with message:" echo -e "\t\t$message" else prnt E "Error ligne $(caller), with error code $code." fi unset parent_lineno message code } # Trigger error function on error trap "error ${LINENO}; backtrace; err_exit" ERR # ------------------------------------------------------------------------------ # Exit program in case of error unless keepgoing is set to true function err_exit { if [[ $KEEPGOING != true ]]; then if [[ -f $tmpfile ]]; then rm -f $tmpfile fi exit 255 fi } # ------------------------------------------------------------------------------ # Print a backtrace function backtrace { echo "========= Call stack =========" typeset -i i=0 local func= for func in "${FUNCNAME[@]}"; do if [[ $i -ne 0 ]]; then printf '%15s() %s:%d\n' \ "$func" "${BASH_SOURCE[$i]}" "${BASH_LINENO[ (( $i - 1)) ]}" fi let i++ || true done unset func i echo "==============================" } # ------------------------------------------------------------------------------ # Execute command outside of error control, echoes ouput error code noerror() { if [[ $1 == "--noout" ]]; then local noout=true shift fi set +o errexit trap - ERR if [[ -n $noout ]]; then $@ > /dev/null 2>&1 else $@ fi echo $? trap "error ${LINENO}" ERR set -o errexit } export -f noerror # ------------------------------------------------------------------------------ # Test and exit if not root (or any UID 0 user) check_root() { if [[ $NO_ROOT_CHECK == true ]]; then return 0 fi if [[ $EUID -ne 0 ]]; then prnt E "check_root: That script must be run with root privileges." die 4 --force fi } export -f check_root # EOF