Initial commit.
This commit is contained in:
150
watchman-svc.bash
Normal file
150
watchman-svc.bash
Normal file
@@ -0,0 +1,150 @@
|
||||
#!@BASH_PATH@
|
||||
|
||||
watchman_version='@VERSION@'
|
||||
|
||||
msg() { printf '%s\n' "$*"; }
|
||||
err() { printf '%s\n' "$*" >&2; }
|
||||
|
||||
usage() {
|
||||
while read; do msg "$REPLY"; done <<- 'EOF'
|
||||
Usage: watchman-svc <-p pidfile> [options] command
|
||||
Flags:
|
||||
-p <pidfile>
|
||||
-l <logfile>
|
||||
-r # Respawn the process if it dies.
|
||||
-h # Show this message.
|
||||
-v # Show version.
|
||||
EOF
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
for i in "$respawn_pid" "$job_pid"; do
|
||||
kill_wait "$i" || {
|
||||
err "Failed to stop child: $i"
|
||||
exit 13
|
||||
}
|
||||
done
|
||||
|
||||
rm -f "$job_pidfile"
|
||||
}
|
||||
|
||||
respawn_cleanup() {
|
||||
kill_wait "$job_pid" || {
|
||||
err "Failed to stop child: $i"
|
||||
exit 13
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
respawn_passthrough() {
|
||||
kill -"$1" "$job_pid"
|
||||
}
|
||||
|
||||
kill_wait() {
|
||||
kill "$1" &>/dev/null
|
||||
|
||||
counter=0
|
||||
while kill -0 "$1" &>/dev/null; do
|
||||
sleep 1
|
||||
(( counter >= 10 )) && { return 1; }
|
||||
(( counter++ ))
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
job_run() {
|
||||
"${cmd[@]}" >&3 2>&3 & job_pid=$!
|
||||
export job_pid
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
job_respawn() {
|
||||
trap 'respawn_cleanup; return' INT TERM
|
||||
|
||||
trap 'respawn_passthrough 1' HUP
|
||||
trap 'respawn_passthrough 10' USR1
|
||||
trap 'respawn_passthrough 12' USR2
|
||||
|
||||
while job_run; do
|
||||
last_run=$SECONDS
|
||||
if kill -0 "$job_pid"; then
|
||||
wait "$job_pid"
|
||||
fi
|
||||
|
||||
curtime=$SECONDS
|
||||
if (( last_run + 1 > ( curtime - 2 ) )); then
|
||||
err "The job exists right as we start it. Bailing."
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
job_wait() {
|
||||
trap cleanup INT TERM
|
||||
|
||||
if (( flag_respawn )); then
|
||||
job_respawn & respawn_pid=$!
|
||||
|
||||
printf '%s' "$respawn_pid" > "$job_pidfile"
|
||||
|
||||
wait "$respawn_pid"
|
||||
else
|
||||
job_run
|
||||
|
||||
printf '%s' "$job_pid" > "$job_pidfile"
|
||||
|
||||
wait "$job_pid"
|
||||
fi
|
||||
|
||||
cleanup
|
||||
}
|
||||
|
||||
main() {
|
||||
while (( $# )); do
|
||||
case "$1" in
|
||||
(-h) usage; return 0;;
|
||||
|
||||
(-p) job_pidfile="$2"; shift;;
|
||||
(-l) job_logfile="$2"; shift;;
|
||||
|
||||
(-r) flag_respawn=1;;
|
||||
|
||||
(-v)
|
||||
printf '%s\n' "$watchman_version"
|
||||
exit 0
|
||||
;;
|
||||
|
||||
(--) shift; break;;
|
||||
(-*)
|
||||
err "Unknown key: $1"
|
||||
usage
|
||||
return 1
|
||||
;;
|
||||
|
||||
(*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -z "$job_pidfile" ]]; then
|
||||
usage
|
||||
return 1
|
||||
fi
|
||||
|
||||
cmd=( "$@" )
|
||||
|
||||
if [[ "$job_logfile" ]]; then
|
||||
exec 3>"$job_logfile"
|
||||
else
|
||||
exec 3>&1
|
||||
fi
|
||||
|
||||
job_wait &
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user