home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.shell
- Path: sparky!uunet!s5!is1.is.morgan.com!is0.is.morgan.com!wpm
- From: wpm@is.morgan.com (W. Phillip Moore)
- Subject: signal traps in Bourne -- various and sundry answers
- In-Reply-To: stevet@oakhill.sps.mot.com's message of 21 Dec 92 22:38:04 GMT
- Message-ID: <WPM.92Dec24130151@exile.is.morgan.com>
- Sender: news@is.morgan.com
- Nntp-Posting-Host: exile
- Organization: Informations Services Dept., Morgan Stanley Japan
- References: <1992Dec21.223804.5764@oakhill.sps.mot.com>
- Date: Thu, 24 Dec 1992 18:01:51 GMT
- Lines: 110
-
-
- Steve> Is there a good way to tell a signal service routine to know which
- Steve> signal invoked it? The script below shows how I'm approaching this,
- Steve> but surely there is a more elegant way... any suggestions?
-
- Try this on for size:
-
- function SignalHandler
- {
- case $1 in
- HUP|INT|QUIT|TERM)
- echo "Caught a SIG$1 -- doing down..." ;;
- KILL|STOP|CONT)
- echo "Hey, I can't catch a SIG$1, what's going on?" ;;
- *)
- echo "Who needs a SIG$1; happily ignoring..."
- esac
- }
-
- for SIGNAL in `kill -l` ; do
- trap "SignalHandler $SIGNAL" $SIGNAL
- done
-
- This assumes that you are using a shell which doesn't have a built-in kill
- which prints a numbered table of signals, such as ksh does. Eg:
-
- kill -l
- 1) HUP 12) SYS 23) POLL
- 2) INT 13) PIPE 24) XCPU
- etc, etc
-
- Will choke of course, but at least in SunOS:
-
- /usr/bin/kill -l
- HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG
- STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH LOST USR1 USR2
-
- is what you're after. It also assumes your shell will use symbolic names,
- rather than integers, as I understand that some older brain-dead versions
- do not.
-
- While we're on the subject of signals and shells, here's something else I
- find quite useful. I have a generic wrapper script for use by our
- developers which handles automatic restarting of user applications, logs
- messages when applications crash, and some other neat stuff you probably
- don't care about. One thing I've provided is special functionailty when a
- SIGUSR1 or SIGUSR2 is received, and in addition I trap on some other
- signals (HUP,INT,TERM) as well, but I don't want to pass these signal traps
- to the child process.
-
- In the parent, I do:
-
- for SIGNAL in $( /usr/bin/kill -l ) ; do
- case $SIGNAL in
- HUP|INT|QUIT|TERM|USR1|USR2)
- trap "SignalHandler $SIGNAL" $SIGNAL ;;
- PIPE|ALRM|WINCH)
- trap - $SIGNAL ; trap "" $SIGNAL ;;
- *) ;;
- esac
- done
-
- But before forking the child and waiting for it:
-
- (
- for SIGNAL in $( /usr/bin/kill -l ); do
- trap - $SIGNAL
- case $SIGNAL in
- USR1|USR2) trap "" $SIGNAL ;;
- *) ;;
- esac
- done
- exec $FULLNAME ${1+"$@"}
- ) &
-
- This restored the signal handler for the subshell to its default state,
- except for USR1 and USR2 which I want the child to ignore.
-
- If you are playing games with waiting for kids, you'll find you have to do
- something ugly to simulate the ERRNO from wait. In csh or perl (the latter
- being much nicer for complicated games with subprocesses and signal
- handling in particular), wait will set ERRNO to EINTR if you catch a signal
- while waiting, but in ksh the variable ERRNO only gets set when a system
- call fails. Dropping out of wait when a signal is caught doesn't set
- this. Bummer.
-
- Since wait will return 0, and you probably need to keep waiting for the
- child anyway, I do something like this:
-
- child &
- CHILD_PID=$!
-
- while true ; do
- unset _SIGNAL_CAUGHT
- wait $CHILD_PID
- CHILD_STATUS=$?
- [[ -z $_SIGNAL_CAUGHT ]] && break
- done
-
- In my SignalHandler function, I set the _SIGNAL_CAUGHT to True, so that I
- can distinguish in the above loop whether or not I was interrupted or the
- child exited.
-
- This is clearly a lot more than you asked for, but I hope people find it
- useful.
-
- W. Phillip Moore Phone: 81-3-3286-9359
- Information Services Department FAX: 81-3-3286-9040
- Morgan Stanley Japan Ltd. Tokyo Branch E-mail: wpm@is.morgan.com
- Ote Center Bldg. 3F, 1-1-3 Otemachi, Chiyoda-ku, Tokyo 100
-