157 lines
4.4 KiB
Bash
157 lines
4.4 KiB
Bash
#!/bin/bash
|
|
# ------------------------------------------------------------------------------
|
|
# Error management functions
|
|
# This file is part of the init.sh project
|
|
# Copyright (c) 2019-2024 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
|
|
# ------------------------------------------------------------------------------
|
|
# 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
|
|
}
|
|
export -f terminate
|
|
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
|
|
}
|
|
export -f error
|
|
# 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
|
|
}
|
|
export -f err_exit
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 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
|
|
(( i++ )) || true
|
|
done
|
|
unset func i
|
|
echo "=============================="
|
|
}
|
|
export -f backtrace
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 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
|