#! /bin/bash

# ./launcher-lock 'for ((i=0;i<10;i++)); do echo | tai64n | tee /dev/stderr | tai64nlocal ; done'

declare -x PIDFILE
declare -x itspid
declare -x myself
declare -x timebase
declare -x maxlifetime
TMP=${TMP:-/tmp}
PIDFILE="$TMP/launcher.lock"
myself=$$
timebase=3
maxlifetime=60

function quickquit() {
	echo "received QUIT"
	kill $itspid && rm "$PIDFILE"
}

function reallyquit() {
	echo "received INT"
	kill $itspid && rm "$PIDFILE"
}

# run given task and assert pidfile
function launch() {
	eval $@ &
	itspid=$!
	if [ -z "$itspid" ]; then
		exit 1
	fi
	sleep 1s
	if ! kill -0 $itspid 2>/dev/null; then
		echo "Task is unsure or quick! (should not use this tool in your case, it's a feature)"
		exit 1
	fi
	echo $itspid > "$PIDFILE"
	if [ ! -e "$PIDFILE" ]; then
		exit 1
	fi
}

# ALRM signal
function longenaugh() {
	if kill -0 $itspid 2>/dev/null; then
		((step++))
		((stoup = step * timebase))
		if ((stoup >= maxlifetime)); then
			echo "kill..."
			kill $itspid
			rm "$PIDFILE"
			exit 1
		fi
	else
		echo "Task is not any more there"
		rm "$PIDFILE"
		exit 0
	fi
}

# trap handlers
trap quickquit SIGQUIT
trap reallyquit SIGINT
trap longenaugh SIGALRM

# we start in good term
if [ -e "$PIDFILE" ]; then
	# ahum..
	itspid=$( cat $PIDFILE )
	if [ -z "$itspid" ]; then
		echo "invalid pidfile, go on"
	else
		if kill -0 $itspid 2>/dev/null; then
			echo "lock file and process respond"
			exit 0
		else
			echo "lock file but process didn't respond"
		fi
	fi
fi

# getopt style...
while [ ! -z "$1" ]; do
	case "$1" in
		-h)
			echo "Usage: $0 [-m(axtime) seconds] [-t(imebase) s] [--] command line"
			exit 0
			;;
		-m)
			shift
			maxlifetime=$1
			shift
			;;
		-t)
			shift
			timebase=$1
			shift
			;;
		--)
			shift
			break
			;;
		*)
			break
			;;
	esac
done

launch $@
((step=timebase))
# wake up to look at the child
while sleep ${timebase}s ; do
	kill -SIGALRM $myself
done

