diff --git a/README.md b/README.md index 69b64cf..e0f11d5 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,15 @@ If `firestarter` is invoked without any arguments, it will attempt to start a se * `list`, `ls`: List all configuration files and, if they are fsdefaults files, resolve them. Useful for debugging. +* `logout`: Kill Firestarter, if it's running. + +* `restart`: Stop a running service and start it back up again. Does not fail on dead services. + * `start`: Start a configuration file, redirecting output to the proper logs and dropping its PID in `/run` for existing Firestarter instances to use. * `status`, `st`, `stat`: Prints information about the running Firestarter session, including PID, display, and the state of all services. -* `stop`: Kill Firestarter, if it's running. +* `stop`: Stop a running service ## Logging diff --git a/firestarter b/firestarter index 2e0f471..f2af349 100755 --- a/firestarter +++ b/firestarter @@ -23,6 +23,8 @@ declare -i _optverbose declare -a _args declare -i _hasdbus declare _return +# Junk FD used for read waiting +exec 1023<> <(:) # Helper functions log() { @@ -107,6 +109,37 @@ gettarget() { done < "$1" return 2 } +fskill() { + # Kill any number of PIDs, validating inputs n stuff + for pid in $@; do + # Sanity checks + [ -z "$pid" ] && continue + [ "$pid" -gt 0 ] 2> /dev/null || warn "Invalid PID: $pid" 2 + [ -d "/proc/$pid" ] || warn "Process is already dead: $pid" 2 + kill "$pid" + ( + exec 1023<> <(:) + for (( i=0; i<10; i++ )); do + kill -0 "$pid" 2> /dev/null || return 0 + read -t 1 -u 1023 || : + done + warn "Force stopping unresponsive process: $pid" + kill -9 "$pid" + ) + done +} +fsstop() { + # Stop a running service by name + for service in $@; do + pidfile="$_optrundir"/"$service".pid + [ -f "$pidfile" ] || warn "Service is not already running: $service" + pid="$(< $pidfile)" + [ "$pid" -gt 0 ] 2> /dev/null || error "PID is invalid for service: $service (PID $pid)" 51 + [ -d "/proc/$pid" ] || warn "Service is already dead: $service" + [ -d "/proc/$pid" ] && fskill "$pid" + return 0 + done +} fsexec() { # Execute an fsdefaults file [ -z "$1" ] && return 1 @@ -448,7 +481,7 @@ step_logout() { fi else # Otherwise just brute it out - kill $(jobs -p) + fskill $(jobs -p) fi return 0 } @@ -468,8 +501,11 @@ provided init Start all services and wait list List all valid services - start Start the provided service, fork, and exit + logout Log out of an existing Firestarter session + restart Stop and restart the provided services + start Start the provided services, fork, and exit status Show status information + stop Stop the provided services Environment Variables: @@ -496,6 +532,12 @@ firestart() { ls|list) fslist ;; + restart) + for file in "${_args[@]:1}"; do + fsstop "$file" + fsexec "$_optconfigdir"/"$file" + done + ;; start) for file in "${_args[@]:1}"; do fsexec "$_optconfigdir"/"$file" @@ -505,6 +547,11 @@ firestart() { fsstatus ;; stop) + for file in "${_args[@]:1}"; do + fsstop "$file" + done + ;; + logout) if [ -n "$FIRESTARTER" ] && [ -d "/proc/$FIRESTARTER" ] && [ "$FIRESTARTER" -gt 0 ] 2> /dev/null; then log "Killing PID $FIRESTARTER" kill $FIRESTARTER