diff --git a/src/clh b/src/clh new file mode 100644 index 0000000..ad82566 --- /dev/null +++ b/src/clh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +LIB_SRC=${LIB_SRC:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)} + +source "${LIB_SRC}/config.bash" +source "${LIB_SRC}/utils.bash" +source "${LIB_SRC}/process_monitor.bash" \ No newline at end of file diff --git a/src/process_monitor.bash b/src/process_monitor.bash index 71fe43c..989a524 100644 --- a/src/process_monitor.bash +++ b/src/process_monitor.bash @@ -33,13 +33,11 @@ clh_start_process_monitor() { ( shutdown=false while ! $shutdown; do - for pid_file in "${_procmon_output}"/*.pid; do - [[ -f "${pid_file}" ]] || continue # null glob - base_name=$(basename "${pid_file}") - pid=${base_name%.pid} + clh_get_tracked_pids + for pid in "${result[@]}"; do if ! kill -0 "${pid}"; then echoerr "[procmon] ${pid} is dead" - rm "${pid_file}" + rm "${_procmon_output}/${pid}.pid" fi sleep 1 done @@ -60,6 +58,7 @@ clh_track_last_background_job() { clh_get_tracked_pids() { result=() for pid_file in "${_procmon_output}"/*.pid; do + [[ -f "${pid_file}" ]] || continue # null glob base_name=$(basename "${pid_file}") pid=${base_name%.pid} result+=("${pid}") @@ -80,7 +79,7 @@ clh_stop_process_monitor() { if [ "$1" = "monitor_only" ]; then echoerr "[procmon] stop monitor only. Children will be left behind." kill -s TERM "$_procmon_pid" - wait "$_procmon_pid" + await "$_procmon_pid" return 0 else echoerr "[procmon] stop process group. This will halt the script." diff --git a/src/utils.bash b/src/utils.bash index da1b505..ce57b2e 100644 --- a/src/utils.bash +++ b/src/utils.bash @@ -11,4 +11,11 @@ clh_output_folder() { echoerr() { echo "$@" >&2 +} + +await() { + local pid=$1 + while kill -0 "$pid"; do + sleep 0.1 + done } \ No newline at end of file diff --git a/test/test_process_monitor.bats b/test/test_process_monitor.bats index 65bfb93..e58d649 100644 --- a/test/test_process_monitor.bats +++ b/test/test_process_monitor.bats @@ -18,29 +18,48 @@ setup() { refute clh_stop_process_monitor } -# @test "should keep track of process PIDs" { -# clh_get_tracked_pids -# assert [ ${#result[@]} -eq 0 ] +@test "should keep track of process IDs" { + echo "hi" + assert clh_start_process_monitor -# ( -# while [ ! -f "${OUTPUT_FOLDER}/stop" ]; do -# sleep 0.1 -# done -# ) & -# clh_track_last_background_job + clh_get_tracked_pids + assert [ ${#result[@]} -eq 0 ] -# ( -# while [ ! -f "${OUTPUT_FOLDER}/stop" ]; do -# sleep 0.1 -# done -# ) & -# clh_track_last_background_job + ( + while true; do + sleep 0.1 + done + ) & + clh_track_last_background_job + p1=$! -# clh_get_tracked_pids -# assert [ ${#result[@]} -eq 2 ] + ( + while true; do + sleep 0.1 + done + ) & + clh_track_last_background_job + p2=$! -# touch "${OUTPUT_FOLDER}/stop" + clh_get_tracked_pids + assert [ ${#result[@]} -eq 2 ] -# clh_get_tracked_pids -# assert [ ${#result[@]} -eq 0 ] -# } + kill -s TERM "$p1" + kill -s TERM "$p2" + + echo "Kill issued" > killissued + + # This will hang the bats runner for some reason. + await "$p1" + await "$p2" + + # This should be more than enough for the process monitor to + # catch the exits. The alternative would be implementing temporal + # predicates. + sleep 3 + + clh_get_tracked_pids + assert [ ${#result[@]} -eq 0 ] + + clh_stop_process_monitor "monitor_only" +}