diff --git a/timeout b/timeout new file mode 100755 index 0000000..38267e7 --- /dev/null +++ b/timeout @@ -0,0 +1,74 @@ +#!/bin/sh + +usage() { + printf "Usage: %s [-t TIMEOUT] [-c COMMAND]\n\n" "$0" + printf "TIMEOUT and COMMAND can be set as env vars.\n" +} + +on_interrupt() { + print "Process aborted!\n" + + exit 130 +} + +create_script() { + printf "#!/bin/sh\n%s\n" "$1" > "$2" + chmod +x "$SCRIPT_FILE" +} + +run_script() { + "$SCRIPT_FILE" >/dev/null 2>&1 & + + printf "%d" $! +} + +stop_delete_script() { + kill -9 $1 + rm -f "$2" +} + +check_pid() { + PID=$1 + LOOP=$2 + + for i in $(seq 1 $LOOP); do + test -d "/proc/$PID/" && sleep 1 || STATUS=0 + done + + kill -9 $PID + + printf "%d" ${STATUS:-1} +} + +main() { + while getopts "ht:c:" option; do + case "${option}" in + h) usage; exit 0;; + t) TIMEOUT="$OPTARG";; + c) COMMAND="$OPTARG";; + *) usage; exit 1;; + esac + done + + TIMEOUT="${TIMEOUT:-10}" + + if [ -z "$COMMAND" ]; then + printf "Command is required!\n" + exit 1 + fi + + SCRIPT_FILE="$(mktemp)" + + create_script "$COMMAND" "$SCRIPT_FILE" + + SCRIPT_PID=$(run_script "$SCRIPT_FILE") + EXIT_STATUS=$(check_pid "$SCRIPT_PID" "$TIMEOUT") + + stop_delete_script $PID "$SCRIPT_FILE" + + exit $EXIT_STATUS +} + +trap on_interrupt INT + +main "$@"