home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / shell / 5187 < prev    next >
Encoding:
Text File  |  1992-12-30  |  4.1 KB  |  124 lines

  1. Newsgroups: comp.unix.shell
  2. Path: sparky!uunet!s5!is1.is.morgan.com!is0.is.morgan.com!wpm
  3. From: wpm@is.morgan.com (W. Phillip Moore)
  4. Subject: signal traps in Bourne -- various and sundry answers
  5. In-Reply-To: stevet@oakhill.sps.mot.com's message of 21 Dec 92 22:38:04 GMT
  6. Message-ID: <WPM.92Dec24130151@exile.is.morgan.com>
  7. Sender: news@is.morgan.com
  8. Nntp-Posting-Host: exile
  9. Organization: Informations Services Dept., Morgan Stanley Japan
  10. References: <1992Dec21.223804.5764@oakhill.sps.mot.com>
  11. Date: Thu, 24 Dec 1992 18:01:51 GMT
  12. Lines: 110
  13.  
  14.  
  15. Steve> Is there a good way to tell a signal service routine to know which
  16. Steve> signal invoked it?  The script below shows how I'm approaching this,
  17. Steve> but surely there is a more elegant way... any suggestions?  
  18.  
  19. Try this on for size:
  20.  
  21. function SignalHandler
  22. {
  23.   case $1 in
  24.     HUP|INT|QUIT|TERM)
  25.       echo "Caught a SIG$1 -- doing down..." ;;
  26.     KILL|STOP|CONT)
  27.       echo "Hey, I can't catch a SIG$1, what's going on?" ;;
  28.     *)
  29.       echo "Who needs a SIG$1; happily ignoring..."
  30.   esac  
  31. }
  32.  
  33. for SIGNAL in `kill -l` ; do
  34.   trap "SignalHandler $SIGNAL" $SIGNAL
  35. done
  36.  
  37. This assumes that you are using a shell which doesn't have a built-in kill
  38. which prints a numbered table of signals, such as ksh does.  Eg:
  39.  
  40. kill -l
  41.  1) HUP                  12) SYS                  23) POLL
  42.  2) INT                  13) PIPE                 24) XCPU
  43. etc, etc
  44.  
  45. Will choke of course, but at least in SunOS:
  46.  
  47. /usr/bin/kill -l
  48. HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG 
  49. STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH LOST USR1 USR2
  50.  
  51. is what you're after.  It also assumes your shell will use symbolic names,
  52. rather than integers, as I understand that some older brain-dead versions
  53. do not.
  54.  
  55. While we're on the subject of signals and shells, here's something else I
  56. find quite useful.  I have a generic wrapper script for use by our
  57. developers which handles automatic restarting of user applications, logs
  58. messages when applications crash, and some other neat stuff you probably
  59. don't care about.  One thing I've provided is special functionailty when a
  60. SIGUSR1 or SIGUSR2 is received, and in addition I trap on some other
  61. signals (HUP,INT,TERM) as well, but I don't want to pass these signal traps
  62. to the child process.
  63.  
  64. In the parent, I do:
  65.  
  66.     for SIGNAL in $( /usr/bin/kill -l ) ; do
  67.       case $SIGNAL in
  68.     HUP|INT|QUIT|TERM|USR1|USR2)
  69.        trap "SignalHandler $SIGNAL" $SIGNAL ;;
  70.     PIPE|ALRM|WINCH)
  71.        trap - $SIGNAL ; trap "" $SIGNAL ;;
  72.     *) ;;
  73.       esac
  74.     done
  75.  
  76. But before forking the child and waiting for it:
  77.  
  78.     (
  79.       for SIGNAL in $( /usr/bin/kill -l ); do
  80.         trap - $SIGNAL
  81.         case $SIGNAL in
  82.           USR1|USR2) trap "" $SIGNAL ;;
  83.                   *) ;;
  84.         esac
  85.       done
  86.       exec $FULLNAME ${1+"$@"}
  87.     ) &
  88.  
  89. This restored the signal handler for the subshell to its default state,
  90. except for USR1 and USR2 which I want the child to ignore.
  91.  
  92. If you are playing games with waiting for kids, you'll find you have to do
  93. something ugly to simulate the ERRNO from wait.  In csh or perl (the latter
  94. being much nicer for complicated games with subprocesses and signal
  95. handling in particular), wait will set ERRNO to EINTR if you catch a signal
  96. while waiting, but in ksh the variable ERRNO only gets set when a system
  97. call fails.  Dropping out of wait when a signal is caught doesn't set
  98. this.  Bummer.
  99.  
  100. Since wait will return 0, and you probably need to keep waiting for the
  101. child anyway, I do something like this:
  102.  
  103.   child &
  104.   CHILD_PID=$!
  105.  
  106.   while true ; do
  107.     unset _SIGNAL_CAUGHT
  108.     wait $CHILD_PID
  109.     CHILD_STATUS=$?
  110.     [[ -z $_SIGNAL_CAUGHT ]] && break
  111.   done
  112.  
  113. In my SignalHandler function, I set the _SIGNAL_CAUGHT to True, so that I
  114. can distinguish in the above loop whether or not I was interrupted or the
  115. child exited.  
  116.  
  117. This is clearly a lot more than you asked for, but I hope people find it
  118. useful.  
  119.  
  120. W. Phillip Moore                                        Phone: 81-3-3286-9359
  121. Information Services Department                           FAX: 81-3-3286-9040
  122. Morgan Stanley Japan Ltd.  Tokyo Branch             E-mail: wpm@is.morgan.com
  123.         Ote Center Bldg. 3F, 1-1-3 Otemachi, Chiyoda-ku, Tokyo 100
  124.