From f4aacc39f0dc1090b3082c2a445a0ea2e89ac84c Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Fri, 01 Jun 2018 19:39:45 -0400 Subject: bin/rc: Ignore SIGHUP and don't halt svc running on error Fix run_services() parameters, function call error handling, the daemon printing to the closed standard error FD, a crash due to an empty session type in the status command, and a crash when given an unwritable status response file name. Also document the session type format. --- diff --git a/bin/rc b/bin/rc index 277c2aa..e96245c 100755 --- a/bin/rc +++ b/bin/rc @@ -43,14 +43,18 @@ valid_session_type() run_services() { local old_sessions="${1}" - local new_sessions="${1}" - shift 1 + local new_sessions="${2}" + shift 2 + local ret= local service_script= + ret=0 for service_script in "${XDG_CACHE_HOME:-${HOME}/.cache}/homerc/"*; do - "$(dirname ${0})/svc" "${service_script##*/}" \ - "${old_sessions};${new_sessions}" + "$(dirname "${0}")/svc" "${service_script##*/}" \ + "${old_sessions};${new_sessions}" || ret=1 done + + return ${ret} } beg_session() @@ -77,8 +81,7 @@ beg_session() new_sessions="${sessions}${session_type}," old_sessions="${sessions}" sessions="${new_sessions}" - run_services "${old_sessions}" "${new_sessions}" - return ${?} + run_services "${old_sessions}" "${new_sessions}" || return 1 fi return 0 @@ -95,7 +98,7 @@ end_session() s_type="$(printf '%s' "${session_type}" | tr ':' '_')" if eval "[ \${sessions_${s_type}:-0} -eq 0 ]"; then - error 'No running sessions of type %s' "${session_type}" + # No running sessions of specified type return 1 fi @@ -108,8 +111,7 @@ end_session() new_sessions="${new_sessions},${sessions#*,${session_type},}" old_sessions="${sessions}" sessions="${new_sessions}" - run_services "${old_sessions}" "${new_sessions}" - return ${?} + run_services "${old_sessions}" "${new_sessions}" || return 1 fi return 0 @@ -124,13 +126,16 @@ list_sessions() IFS=',' for session in ${sessions}; do unset IFS + case "${session}" in '') continue;; esac if ${printed}; then printf ', ' fi - eval "printf '%s (%d)' '${session}' \${sessions_${session}}" + eval "printf '%s (%d)' \"\${session}\" \${sessions_${session}}" printed=true done unset IFS + + return 0 } listen() @@ -141,18 +146,11 @@ listen() while :; do if read -r magic cmd arg; then - case "${magic}" in "${MAGIC}");; *) - continue - esac + case "${magic}" in "${MAGIC}");; *) continue;; esac case "${cmd}" in - 'beg') + 'beg' | 'end') if valid_session_type "${arg}"; then - beg_session "${arg}" - fi - ;; - 'end') - if valid_session_type "${arg}"; then - end_session "${arg}" + "${cmd}_session" "${arg}" || : fi ;; 'who') @@ -160,7 +158,7 @@ listen() printf '%s ' "${MAGIC}" list_sessions printf '\n' - } 1>"${arg}" + } 1>"${arg}" || : ;; 'bye') break @@ -171,6 +169,8 @@ listen() esac fi done 0<"${rc_fifo}" + + return 0 } run_daemon() @@ -180,10 +180,7 @@ run_daemon() local piddir= exec 0<&- 1>&- 2>&- - # TODO: - # Disassociate from its process group (usually a shell), to insulate - # itself from signals (such as HUP) sent to the process group - # Ignore all terminal I/O signals + trap '' HUP piddir="${XDG_CACHE_HOME:-${HOME}/.cache}/homerc" mkdir -p "${piddir}" @@ -191,6 +188,7 @@ run_daemon() beg_session "${session_type}" listen + rm "${rc_fifo}" rm -f "${piddir}/"* @@ -251,11 +249,10 @@ status() # Signal the running rc daemon. printf "%s who %s\n" "${MAGIC}" "${res_fifo}" \ 1>"${rc_fifo}" - if read -r magic list; then - case "${magic}" in "${MAGIC}");; *) - continue - esac + if read -r magic list 0<"${res_fifo}" && \ + [ "x${magic}" = "x${MAGIC}" ]; then info 'Sessions: %s' "${list}" + rm "${res_fifo}" else error 'Failed to communicate with running daemon' rm "${res_fifo}" @@ -269,40 +266,36 @@ status() usage() { printf 'Usage: %s {start|stop} \n' "${0}" - printf ' or: %s status\n' "${0}" + printf ' or: %s status\n\n' "${0}" + printf ' is one or more strings of alphanumeric ' + printf 'characters\nseparated by colons.\n' return 0 } main() { - local action= - local session_type= - - if [ ${#} -ne 2 ]; then - usage 1>&2 - return 1 - fi - action="${1}" - session_type="${2}" - - if ! valid_session_type; then - error 'Invalid session type' - return 1 - fi + local action="${1-}" + local session_type="${2-}" progname="${0##*/}" rc_fifo="/tmp/homercrc-$(id -u)" res_fifo="/tmp/homercres-${$}" case "${action}" in - 'start') - start "${session_type}" - ;; - 'stop') - stop "${session_type}" + 'start' | 'stop') + if [ ${#} -ne 2 ] || valid_session_type \ + "${session_type}"; then + usage 1>&2 + return 1 + fi + "${action}" "${session_type}" ;; 'status') + if [ ${#} -ne 1 ]; then + usage 1>&2 + return 1 + fi status ;; *) -- cgit v0.9.1