151 lines
2.1 KiB
Bash
151 lines
2.1 KiB
Bash
#!@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 "$@"
|