Page MenuHomeFreeBSD

D46552.id143043.diff
No OneTemporary

D46552.id143043.diff

diff --git a/libexec/rc/Makefile b/libexec/rc/Makefile
--- a/libexec/rc/Makefile
+++ b/libexec/rc/Makefile
@@ -18,7 +18,7 @@
CONFETCDEFAULTSPACKAGE= rc
FILESGROUPS= LIBEXEC_SCRIPTS
-LIBEXEC_SCRIPTS= debug.sh safe_eval.sh
+LIBEXEC_SCRIPTS= debug.sh hooks.sh safe_eval.sh
LIBEXEC_SCRIPTSDIR= /libexec
LIBEXEC_SCRIPTSMODE= 755
LIBEXEC_SCRIPTSPACKAGE= rc
diff --git a/libexec/rc/debug.sh b/libexec/rc/debug.sh
--- a/libexec/rc/debug.sh
+++ b/libexec/rc/debug.sh
@@ -74,7 +74,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: debug.sh,v 1.35 2024/02/03 19:04:47 sjg Exp $
+# $Id: debug.sh,v 1.39 2024/09/06 16:56:50 sjg Exp $
#
# @(#) Copyright (c) 1994-2024 Simon J. Gerraty
#
@@ -93,11 +93,37 @@
Myname=${Myname:-`basename $0 .sh`}
+# We want to use local if we can
+# if isposix-shell.sh has been sourced isPOSIX_SHELL will be set
+# as will local
+case "$local" in
+local|:) ;;
+*)
+ if (echo ${PATH%:*}) > /dev/null 2>&1; then
+ local=local
+ else
+ local=:
+ fi
+ ;;
+esac
+
DEBUGGING=
DEBUG_DO=:
DEBUG_SKIP=
export DEBUGGING DEBUG_DO DEBUG_SKIP
+##
+# _debugOn match first
+#
+# Actually turn on tracing, set $DEBUG_ON=$match
+#
+# If we have included hooks.sh $_HOOKS_SH will be set
+# and if $first (the first arg to DebugOn) is suitable as a variable
+# name we will run ${first}_debugOn_hooks.
+#
+# We disable tracing for hooks_run itself but functions can trace
+# if they want based on DEBUG_DO
+#
_debugOn() {
DEBUG_OFF=
DEBUG_DO=
@@ -105,11 +131,36 @@
DEBUG_X=-x
set -x
DEBUG_ON=$1
+ case "$_HOOKS_SH,$2" in
+ ,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
+ *) # avoid noise from hooks_run
+ set +x
+ hooks_run ${2}_debugOn_hooks
+ set -x
+ ;;
+ esac
}
+##
+# _debugOff match $DEBUG_ON $first
+#
+# Actually turn off tracing, set $DEBUG_OFF=$match
+#
+# If we have included hooks.sh $_HOOKS_SH will be set
+# and if $first (the first arg to DebugOff) is suitable as a variable
+# name we will run ${first}_debugOff_hooks.
+#
+# We do hooks_run after turning off tracing, but before resetting
+# DEBUG_DO so functions can trace if they want
+#
_debugOff() {
DEBUG_OFF=$1
set +x
+ case "$_HOOKS_SH,$3" in
+ ,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
+ *) hooks_run ${3}_debugOff_hooks;;
+ esac
+ set +x # just to be sure
DEBUG_ON=$2
DEBUG_DO=:
DEBUG_SKIP=
@@ -120,16 +171,30 @@
$DEBUG_DO echo "$@"
}
+##
+# Debugging
+#
+# return 0 if we are debugging.
+#
Debugging() {
test "$DEBUG_SKIP"
}
+##
+# DebugLog message
+#
+# Outout message with timestamp if we are debugging
+#
DebugLog() {
$DEBUG_SKIP return 0
echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@"
}
-# something hard to miss when wading through huge -x output
+##
+# DebugTrace message
+#
+# Something hard to miss when wading through huge -x output
+#
DebugTrace() {
$DEBUG_SKIP return 0
set +x
@@ -139,8 +204,13 @@
set -x
}
-# Turn on debugging if appropriate
+##
+# DebugOn [-e] [-o] match ...
+#
+# Turn on debugging if any $match is found in $DEBUG_SH.
+#
DebugOn() {
+ eval ${local:-:} _e _match _off _rc
_rc=0 # avoid problems with set -e
_off=:
while :
@@ -170,14 +240,14 @@
*,!$_e,*|*,!$Myname:$_e,*)
# only turn it off if it was on
_rc=0
- $DEBUG_DO _debugOff $_e $DEBUG_ON
+ $DEBUG_DO _debugOff $_e $DEBUG_ON $1
break
;;
*,$_e,*|*,$Myname:$_e,*)
# only turn it on if it was off
_rc=0
_match=$_e
- $DEBUG_SKIP _debugOn $_e
+ $DEBUG_SKIP _debugOn $_e $1
break
;;
esac
@@ -185,7 +255,7 @@
if test -z "$_off$_match"; then
# off unless explicit match, but
# only turn it off if it was on
- $DEBUG_DO _debugOff $_e $DEBUG_ON
+ $DEBUG_DO _debugOff $_e $DEBUG_ON $1
fi
DEBUGGING=$DEBUG_SKIP # backwards compatability
$DEBUG_DO set -x # back on if needed
@@ -193,11 +263,20 @@
return $_rc
}
+##
+# DebugOff [-e] [-o] [rc=$?] match ...
+#
# Only turn debugging off if one of our args was the reason it
# was turned on.
+#
# We normally return 0, but caller can pass rc=$? as first arg
# so that we preserve the status of last statement.
+#
+# The options '-e' and '-o' are ignored, they just make it easier to
+# keep DebugOn and DebugOff lines in sync.
+#
DebugOff() {
+ eval ${local:-:} _e _rc
case ",${DEBUG_SH:-$DEBUG}," in
*,[Dd]ebug,*) ;;
*) $DEBUG_DO set +x;; # reduce the noise
@@ -216,7 +295,7 @@
: $_e==$DEBUG_OFF DEBUG_OFF
case "$DEBUG_OFF" in
"") break;;
- $_e) _debugOn $DEBUG_ON; return $_rc;;
+ $_e) _debugOn $DEBUG_ON $1; return $_rc;;
esac
done
for _e in $*
@@ -224,7 +303,7 @@
: $_e==$DEBUG_ON DEBUG_ON
case "$DEBUG_ON" in
"") break;;
- $_e) _debugOff; return $_rc;;
+ $_e) _debugOff "" "" $1; return $_rc;;
esac
done
DEBUGGING=$DEBUG_SKIP # backwards compatability
@@ -247,6 +326,7 @@
# Run an interactive shell if appropriate
# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn
DebugShell() {
+ eval ${local:-:} _e
case "$_TTY%${DEBUG_INTERACTIVE}" in
*%|%*) return 0;; # no tty or no spec
esac
diff --git a/libexec/rc/hooks.sh b/libexec/rc/hooks.sh
new file mode 100755
--- /dev/null
+++ b/libexec/rc/hooks.sh
@@ -0,0 +1,276 @@
+:
+# SPDX-License-Identifier: BSD-2-Clause
+
+# NAME:
+# hooks.sh - provide hooks for customization
+#
+# SYNOPSIS:
+# hooks_add_all HOOKS [--first] func [...]
+# hooks_add_once HOOKS [--first] func [...]
+# hooks_add_default_set {all,once}
+# hooks_add HOOKS func [...]
+# hooks_get [--lifo] HOOKS
+# hooks_run [--lifo] HOOKS ["args"]
+# hooks_run_all [--lifo] HOOKS ["args"]
+# hooks_has HOOKS func
+#
+# add_hooks HOOKS [--first] func [...]
+# run_hooks HOOKS [LIFO] ["args"]
+# run_hooks_all HOOKS [LIFO] ["args"]
+#
+# DESCRIPTION:
+# The functions add_hooks and run_hooks are retained for
+# backwards compatability. They are aliases for hooks_add and
+# hooks_run.
+#
+# hooks_add_all simply adds the "func"s to the list "HOOKS".
+#
+# If the first arg is '--first' "func"s are added to the start
+# of the list.
+#
+# hooks_add_once does the same but only if "func" is not in "HOOKS".
+# hooks_add uses one of the above based on "option", '--all' (default)
+# or '--once'.
+#
+# hooks_add_default_set sets the default behavior of hooks_add
+#
+# hooks_get simply returns the named list of functions.
+#
+# hooks_has indicates whether "func" in in "HOOKS".
+#
+# hooks_run runs each "func" in $HOOKS and stops if any of them
+# return a bad status.
+#
+# hooks_run_all does the same but does not stop on error.
+#
+# If run_hooks or run_hooks_all is given a flag of '--lifo' or
+# 2nd argument of LIFO the hooks are run in the reverse order of
+# calls to hooks_add.
+# Any "args" specified are passed to each hook function.
+#
+
+# RCSid:
+# $Id: hooks.sh,v 1.21 2024/09/06 16:53:45 sjg Exp $
+#
+# @(#)Copyright (c) 2000-2024 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+
+# avoid multiple inclusion
+_HOOKS_SH=:
+
+# We want to use local if we can
+# if isposix-shell.sh has been sourced isPOSIX_SHELL will be set
+# as will local
+case "$local" in
+local|:) ;;
+*) if (echo ${PATH%:*}) > /dev/null 2>&1; then
+ local=local
+ else
+ local=:
+ fi
+ ;;
+esac
+
+##
+# hooks_add_all list func ...
+#
+# add "func"s to "list" regardless
+#
+hooks_add_all() {
+ eval $local __h
+ __h=$1; shift
+ case "$1" in
+ --first)
+ shift
+ eval "$__h=\"$* \$$__h\""
+ ;;
+ *) eval "$__h=\"\$$__h $*\"";;
+ esac
+}
+
+##
+# hooks_add_once list func ...
+#
+# add "func"s to "list" if not already there
+#
+hooks_add_once() {
+ eval $local __h __hh __first
+ __h=$1; shift
+ case "$1" in
+ --first) shift; __first=:;;
+ *) __first=;;
+ esac
+ eval "__hh=\$$__h"
+ while [ $# -gt 0 ]
+ do
+ : __hh="$__hh" 1="$1"
+ case "$__first $__hh " in
+ *" $1 "*) ;; # dupe
+ :*) __hh="$1 $__hh";;
+ *) __hh="$__hh $1";;
+ esac
+ shift
+ done
+ eval "$__h=\"$__hh\""
+}
+
+##
+# hooks_add_default_set [--]{all,once}
+#
+# change the default method of hooks_add
+#
+hooks_add_default_set() {
+ case "$1" in
+ once|--once) HOOKS_ADD_DEFAULT=once;;
+ *) HOOKS_ADD_DEFAULT=all;;
+ esac
+}
+
+##
+# hooks_add [--{all,once}] list func ...
+#
+# add "func"s to "list"
+#
+# If '--once' use hooks_add_once,
+# default is hooks_add_all.
+#
+hooks_add() {
+ case "$1" in
+ --all) shift; hooks_add_all "$@";;
+ --once) shift; hooks_add_once "$@";;
+ *) hooks_add_${HOOKS_ADD_DEFAULT:-all} "$@";;
+ esac
+}
+
+##
+# hooks_get [--lifo] list [LIFO]
+#
+# return $list
+#
+hooks_get() {
+ eval $local __h __h2 e __l
+ case "$1" in
+ --lifo) __l=LIFO; shift;;
+ esac
+ eval "__h=\$$1"
+ case "$__l$2" in
+ LIFO*)
+ __h2="$__h"
+ __h=
+ for e in $__h2
+ do
+ __h="$e $__h"
+ done
+ ;;
+ esac
+ echo "$__h"
+}
+
+##
+# hooks_has list func
+#
+# is func in $list ?
+#
+hooks_has() {
+ eval $local __h
+ eval "__h=\$$1"
+ case " $__h " in
+ *" $1 "*) return 0;;
+ esac
+ return 1
+}
+
+##
+# hooks_run [--all] [--lifo] list [LIFO] [args]
+#
+# pass "args" to each function in "list"
+# Without '--all'; if any return non-zero return that immediately
+#
+hooks_run() {
+ eval $local __a e __h __hl __h2 __l
+ __a=return
+ __l=
+
+ while :
+ do
+ case "$1" in
+ --all) __a=:; shift;;
+ --lifo) __l=$1; shift;;
+ *) break;;
+ esac
+ done
+ __hl=$1; shift
+ case "$1" in
+ LIFO) __l=--lifo; shift;;
+ esac
+ __h=`hooks_get $__l $__hl`
+ for e in $__h
+ do
+ $e "$@" || $__a $?
+ done
+}
+
+##
+# hooks_run_all [--lifo] list [LIFO] [args]
+#
+# pass "args" to each function in "list"
+#
+hooks_run_all() {
+ hooks_run --all "$@"
+}
+
+##
+# add_hooks,run_hooks[_all] aliases
+#
+add_hooks() {
+ hooks_add "$@"
+}
+
+run_hooks() {
+ hooks_run "$@"
+}
+
+run_hooks_all() {
+ hooks_run --all "$@"
+}
+
+
+case /$0 in
+*/hooks.sh)
+ # simple unit-test
+ list=HOOKS
+ flags=
+ while :
+ do
+ : 1=$1
+ case "$1" in
+ HOOKS|*hooks) list=$1; shift;;
+ --*) flags="$flags $1"; shift;;
+ *) break;;
+ esac
+ done
+ for f in "$@"
+ do
+ : f=$f
+ case "$f" in
+ LIFO) ;;
+ false|true) ;;
+ *) eval "$f() { echo This is $f; }";;
+ esac
+ done
+ echo hooks_add $flags $list "$@"
+ hooks_add $flags $list "$@"
+ echo hooks_run $list
+ hooks_run $list
+ echo hooks_run --all --lifo $list
+ hooks_run --all --lifo $list
+ echo hooks_run $list LIFO
+ hooks_run $list LIFO
+ ;;
+esac

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 8, 8:39 AM (16 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14531431
Default Alt Text
D46552.id143043.diff (10 KB)

Event Timeline