diff --git a/sm b/sm index 2e8b786..7adf970 100755 --- a/sm +++ b/sm @@ -21,22 +21,23 @@ die() { ## Run the command and wait for it to die svc() { + declare job_pid + svc::cleanup() { - kill -n "$service_stop_signal" "$service_pid" + kill -n "$service_stop_signal" "$job_pid" pid_wait "$service_pid" && { rm -f $svc_pidfile $service_ready_flag } - }; trap 'svc::cleanup' TERM INT + }; trap 'svc::cleanup' TERM svc::reload() { - kill -n "$service_reload_signal" "$service_pid" + kill -n "$service_reload_signal" "$job_pid" }; trap 'svc::reload' HUP - "$@" & - service_pid=$! + "$@" & job_pid=$! - while nullexec kill -n 0 "$service_pid"; do + while nullexec kill -n 0 "$job_pid"; do wait done } @@ -44,16 +45,22 @@ svc() { #cat >/dev/null << EOF ## Respawn respawn() { + declare jobs job_pid + respawn::cleanup() { - kill -n 15 $(jobs -p) - wait + jobs=( $(jobs -p) ) + + if [[ "$jobs" ]]; then + kill -n 15 "${jobs[@]}" + wait "${jobs[@]}" + fi + exit 0 }; trap 'respawn::cleanup' TERM while true; do - exec "$@" & - job_pid=$! - wait + exec "$@" & job_pid=$! + wait "$job_pid" done } #EOF @@ -159,14 +166,18 @@ super_start() { svc_pid=$! printf '%s' "$svc_pid" > "$svc_pidfile" - else - "${service_command[@]}" & - fi - if timer "$service_ready_timeout" ready; then - printf '1' > "$service_ready_flag" + if timer "$service_ready_timeout" ready; then + printf '1' > "$service_ready_flag" + else + return 5 + fi + elif (( service_oneshot )); then + "${service_command[@]}"; res=$? + (( $res )) && return "$res" + printf '1' > "$service_enabled_flag" else - return 5 + exec "${service_command[@]}" & fi return 0 @@ -182,19 +193,31 @@ super_oneshot() { super_reload() { (( service_running )) || return 3 - kill -n 1 "$service_pid" + if (( service_managed )); then + kill -n 1 "$service_pid" + else + kill -n "$service_reload_signal" "$service_pid" + fi } ## Stop the service ## Returns: ## 3: Service is not running. super_stop() { - (( service_running )) || return 3 + if (( service_oneshot )); then + (( service_enabled )) || return 3 - nullexec kill -n "$service_stop_signal" "$service_pid" || return 1 - pid_wait "$service_pid" || return 5 + rm -f "$service_enabled_flag" - return 0 + return 0 + else + (( service_running )) || return 3 + + nullexec kill -n "$service_stop_signal" "$service_pid" || return 1 + pid_wait "$service_pid" || return 5 + + return 0 + fi } # Overloadable functions @@ -211,6 +234,7 @@ logs() { cat "$service_logfile"; } ## Status is a bit of a special case. It's talkative. status() { (( service_running )) && return 0 + (( service_enabled )) && return 0 return 1 } @@ -266,6 +290,7 @@ main() { # Legacy [[ "$service_args" ]] && service_command=( "${service_command[@]}" "${service_args[@]}" ) [[ "$service_respawn" == 'true' ]] && service_respawn=1 + [[ "$service_type" == 'oneshot' ]] && { service_oneshot=1; service_managed=0; } [[ "$service_pidfile" ]] && service_managed=0 @@ -281,6 +306,7 @@ main() { default service_stop_signal 15 default service_reload_signal 1 default service_ready_flag "$rundir/$service_name.ready" + default service_enabled_flag "$rundir/$service_name.enabled" # Let's see if there's a PID if [[ -f "$service_pidfile" ]]; then @@ -292,6 +318,12 @@ main() { fi fi + # Maybe the service is enabled? + if [[ -f "$service_enabled_flag" ]]; then + # Yay, it is! + service_enabled=1 + fi + # Check if action is even defined is_function "$2" || die 17 "Function $2 is not defined for $service_name." @@ -348,8 +380,20 @@ main() { status; res=$? case "$res" in - 0) printf '%s is running/enabled.\n' "$service_name";; - 1) printf '%s is not running/enabled.\n' "$service_name";; + 0) + if (( service_oneshot )); then + printf '%s is enabled.\n' "$service_name" + else + printf '%s is running.\n' "$service_name" + fi;; + + 1) + if (( service_oneshot )); then + printf '%s is not enabled.\n' "$service_name" + else + printf '%s is not running.\n' "$service_name" + fi;; + *) printf '%s: status unknown.\n' "$service_name";; esac ;;