Killing the correct process

Maarten Litmaath maart at cs.vu.nl
Sat Feb 17 16:55:16 AEST 1990


In article <1221 at root44.co.uk>,
	gwc at root.co.uk (Geoff Clare) writes:
)...  The '-v' would
)not normally be used in this simple case.  It is there to provide extra
)information about *which* command was timed out, in the event of several
)parallel "timeout" commands.

I still want the verbose info to appear synchronously (see below).

)Also, the delay is a direct result of allowing the process time to
)clean up.  Using a straight 'kill -9' as your script did would mean
)the verbose message would appear before the prompt.  The very slight
)delay in providing the additional information is a small price to pay
)for allowing the timed out process to tidy up.

In your script the delay is always 2 seconds; in the latest version of my
script it's a parameter.

)>To get a synchronous message I had to have a *child* execute the command
)>supplied, while the *parent* reports the status.
)
)But this has a very serious drawback - you lose the exit status of the
)executed command.  The command could die horribly with no error message,
)and you would not know about it!  All your script tells you is whether
)the command completed within the timeout period or not.

Right; fixed in the current version (easy).

)>Another bug in your script is shown by the following example:
)>
)>[stuff deleted]
)>
)>You leave useless processes hanging around!
)
)Leaving a harmless sleep command behind will not usually cause any
)problems.  It will get zapped when the user logs out, if it hasn't
)completed by then.  [...]

What if the command wasn't started from a terminal?  Not nice.
Unnecessary too.
Another plus of timeout 5.0: the signal is now a parameter too.
Now it's your turn again, Geoff! :-)
--------------------cut here--------------------
#!/bin/sh
# @(#)timeout 5.0 90/02/17 Maarten Litmaath

prog=`basename $0`
verbose=0
SIG=-KILL
sigopt=0
sleep=:
timeout=10
usage="Usage: $prog [-v] [-signal] [timeout] [+delay] [--] <command>"

while :
do
	case $1 in
	--)
		shift
		break
		;;
	-v)
		verbose=1
		;;
	-*)
		SIG=$1
		sigopt=1
		;;
	+*)
		EXPR='..\(.*\)'
		delay=`expr x"$1" : "$EXPR"`
		sleep="kill -0 \$\$ && sleep $delay && kill -KILL \$\$"
		case $sigopt in
		0)
			SIG=-TERM
		esac
		;;
	[0-9]*)
		timeout=$1
		;;
	*)
		break
	esac
	shift
done

case $# in
0)
	echo "$usage" >&2
	exit 2
esac

exec 3>&1

pid=`
	sh -c '
		(sleep '$timeout' > /dev/null & echo $!; exec >&-; wait;
		kill '$SIG' $$ && '"$sleep"') 2> /dev/null & exec "$@" >&3 3>&-
	' $prog "$@"
`
status=$?

kill -9 $pid 2> /dev/null || {
	test $verbose = 1 && echo "TIMEOUT: $*" >&2
}
exit $status
--------------------cut here--------------------
--
  "Ever since the discovery of domain addresses in the French cave paintings
  ..."  (Richard Sexton)        |  maart at cs.vu.nl,  uunet!mcsun!botter!maart



More information about the Comp.unix.questions mailing list