(Nonstandard Signals): Renamed from Other Signals.
authorrms <rms>
Mon, 26 Oct 1992 05:49:54 +0000 (05:49 +0000)
committerrms <rms>
Mon, 26 Oct 1992 05:49:54 +0000 (05:49 +0000)
(COREFILE): Envvar documented.
(SIGFPE): Document the subcodes, FPE_*.
(SIGPIPE): Mention EPIPE.
(Signal Messages): These fns are not portable.  Describe sys_siglist.
(Termination in Handler): No need for example to disestablish the handler.
Don't say the example is from Emacs.
(Kill Example): Explain busy-waiting is bad.
(Remembering a Signal): Use ++ and -- to change defer_signal.
(Sigsuspend): Rewritten.

manual/signal.texi

index d473fe5..4f64cd0 100644 (file)
@@ -224,9 +224,8 @@ defined.  Since the signal numbers are allocated consecutively,
 * Alarm Signals::               Used to indicate expiration of timers.
 * Asynchronous I/O Signals::    Used to indicate input is available.
 * Job Control Signals::         Signals used to support job control.
-@c !!! these 2 are not a good combination of titles
 * Miscellaneous Signals::       Miscellaneous Signals.
-* Other Signals::               Implementations can support other signals.
+* Nonstandard Signals::         Implementations can support other signals.
 * Signal Messages::             Printing a message describing a signal.
 @end menu
 
@@ -260,13 +259,15 @@ for them that return normally, your program will probably break horribly
 when such signals happen, unless they are generated by @code{raise} or
 @code{kill} instead of a real error.
 
+@vindex COREFILE
 When one of these program error signals terminates a process, it also
 writes a @dfn{core dump file} which records the state of the process at
 the time of termination.  The core dump file is named @file{core} and is
 written in whichever directory is current in the process at the time.
-The purpose of core dump files is so that you can examine them with a
-debugger to investigate what caused the error.
-@c !!! in GNU, the `COREFILE' env variable specifies the name
+(On the GNU system, you can specify the file name for core dumps with
+the environment variable @code{COREFILE}.)  The purpose of core dump
+files is so that you can examine them with a debugger to investigate
+what caused the error.
 
 @comment signal.h
 @comment ANSI
@@ -289,14 +290,74 @@ defines various floating-point exceptions and requires conforming
 computer systems to report their occurrences.  However, this standard
 does not specify how the exceptions are reported, or what kinds of
 handling and control the operating system can offer to the programmer.
-If you're writing a library of numeric routines that has to be able to
-trap and deal with the different kinds of exceptions intelligently,
-you'll have to look at the documentation for your specific computer and
-operating system to find out how.
-
-@c !!! there is a subcode passed to the handler which says
 @end deftypevr
 
+BSD systems provide the @code{SIGFPE} handler with an extra argument
+that distinguishes various causes of the exception.  In order to access
+this argument, you must define the handler to accept two arguments,
+which means you must cast it to a one-argument function type in order to
+establish the handler.  The GNU library does provide this extra
+argument, but the value is meaningful only on operating systems that
+provide the information (BSD systems and GNU systems).
+
+@table @code
+@comment signal.h
+@comment BSD
+@item FPE_INTOVF_TRAP
+@vindex FPE_INTOVF_TRAP
+Integer overflow (impossible in a C program unless you enable overflow
+trapping in a hardware-specific fashion).
+@comment signal.h
+@comment BSD
+@item FPE_INTDIV_TRAP
+@vindex FPE_INTDIV_TRAP
+Integer division by zero.
+@comment signal.h
+@comment BSD
+@item FPE_SUBRNG_TRAP
+@vindex FPE_SUBRNG_TRAP
+Subscript-range (something that C programs never check for).
+@comment signal.h
+@comment BSD
+@item FPE_FLTOVF_TRAP
+@vindex FPE_FLTOVF_TRAP
+Floating overflow trap.
+@comment signal.h
+@comment BSD
+@item FPE_FLTDIV_TRAP
+@vindex FPE_FLTDIV_TRAP
+Floating/decimal division by zero.
+@comment signal.h
+@comment BSD
+@item FPE_FLTUND_TRAP
+@vindex FPE_FLTUND_TRAP
+Floating underflow trap.  (Trapping on floating underflow is not
+normally enabled.)
+@comment signal.h
+@comment BSD
+@item FPE_DECOVF_TRAP
+@vindex FPE_DECOVF_TRAP
+Decimal overflow trap.  (Only a few machines have decimal arithmetic and
+C never uses it.)
+@ignore @c These seem redundant
+@comment signal.h
+@comment BSD
+@item FPE_FLTOVF_FAULT
+@vindex FPE_FLTOVF_FAULT
+Floating overflow fault.
+@comment signal.h
+@comment BSD
+@item FPE_FLTDIV_FAULT
+@vindex FPE_FLTDIV_FAULT
+Floating divide by zero fault.
+@comment signal.h
+@comment BSD
+@item FPE_FLTUND_FAULT
+@vindex FPE_FLTUND_FAULT
+Floating underflow fault.
+@end ignore
+@end table
+
 @comment signal.h
 @comment ANSI
 @deftypevr Macro int SIGILL
@@ -536,7 +597,6 @@ socket.  @xref{Out-of-Band Data}.
 These signals are used to support job control.  If your system
 doesn't support job control, then these macros are defined but the
 signals themselves can't be raised or handled.
-@c !!! no; only the signals each OS has are defined.
 
 You should generally leave these signals alone unless you really
 understand how job control works.  @xref{Job Control}.
@@ -651,24 +711,21 @@ action for all of them is to cause the process to terminate.
 @comment signal.h
 @comment POSIX.1
 @deftypevr Macro int SIGPIPE
+@cindex pipe signal
+@cindex broken pipe signal
 If you use pipes or FIFOs, you have to design your application so that
 one process opens the pipe for reading before another starts writing.
-If the reading process never starts, or terminates unexpectedly, a write
-to the pipe or FIFO causes the writing process to receive a
-@code{SIGPIPE} signal.
+If the reading process never starts, or terminates unexpectedly, writing
+to the pipe or FIFO raises a @code{SIGPIPE} signal.  If @code{SIGPIPE}
+is blocked, handled or ignored, the offending call fails with
+@code{EPIPE} instead.
 
 Pipes and FIFO special files are discussed in more detail in @ref{Pipes
 and FIFOs}.
 
-@code{SIGPIPE} also occurs when you try to output to a socket that isn't
-connected.  @xref{Sending Data}.
-
-@c !!! rms check my writing
-If @code{SIGPIPE} is blocked or ignored, the offending call fails with
-@code{EPIPE} instead.
+Another cause of @code{SIGPIPE} is when you try to output to a socket
+that isn't connected.  @xref{Sending Data}.
 @end deftypevr
-@cindex pipe signal
-@cindex broken pipe signal
 
 @need 245
 @comment signal.h
@@ -688,8 +745,8 @@ in @ref{Signaling Another Process}.
 @end deftypevr
 @cindex user signals
 
-@node Other Signals
-@subsection Other Signals
+@node Nonstandard Signals
+@subsection Nonstandard Signals
 
 Particular operating systems support additional signals not listed
 above.  The ANSI C standard reserves all identifiers beginning with
@@ -757,15 +814,12 @@ ignore it.
 @cindex signal messages
 
 We mentioned above that the shell prints a message describing the signal
-that terminated a child process.  The clean and portable way to print a
-message describing a signal is to use the functions @code{strsignal} and
+that terminated a child process.  The clean way to print a message
+describing a signal is to use the functions @code{strsignal} and
 @code{psignal}.  These functions use a signal number to specify which
 kind of signal to describe.  The signal number may come from the
 termination status of a child process (@pxref{Process Completion}) or it
 may come from a signal handler in the same process.
-@c !!! not really portable---strsignal is a GNU extension
-
-@c !!! document sys_siglist?
 
 @comment string.h
 @comment GNU
@@ -777,7 +831,8 @@ rewritten on subsequent calls, you should save a copy of it if you need
 to reference it later.
 
 @pindex string.h
-This function is declared in the header file @file{string.h}.
+This function is a GNU extension, declared in the header file
+@file{string.h}.
 @end deftypefun
 
 @comment stdio.h
@@ -796,9 +851,14 @@ character to separate the @var{message} from the string corresponding
 to @var{signum}.
 
 @pindex stdio.h
-This function is declared in the header file @file{stdio.h}.
+This function is a BSD feature, declared in the header file @file{stdio.h}.
 @end deftypefun
 
+@vindex sys_siglist
+There is also an array @code{sys_siglist} which contains the messages
+for the various signal codes.  This array exists on BSD systems, unlike
+@code{strsignal}.
+
 @node Signal Actions
 @section Specifying Signal Actions
 @cindex signal actions
@@ -1336,9 +1396,8 @@ orderly cleanup or recovery from program error signals and interactive
 interrupts.
 
 The cleanest way for a handler to terminate the process is to raise the
-same signal that ran the handler in the first place---but disestablish
-the handler, so it does not run again.  For example, GNU Emacs sets up a
-handler for most fatal signals that looks something like:
+same signal that ran the handler in the first place.  Here is how to do
+this:
 
 @example
 volatile sig_atomic_t fatal_error_in_progress = 0;
@@ -1346,12 +1405,6 @@ volatile sig_atomic_t fatal_error_in_progress = 0;
 void
 fatal_error_signal (int sig)
 @{
-@c !!! this is not necessary in posix.1, right?  but need to unblock signals.
-  /* @r{Immediately set the action for this signal back to the default.}
-     @r{This will prevent the handler from being invoked recursively if}
-     @r{another fatal signal happens while the handler is executing.} */
-  signal (sig, SIG_DFL);
-
 @group
   /* @r{Since this handler is established for more than one kind of signal, }
      @r{it might still get invoked recursively by delivery of some other kind}
@@ -1365,16 +1418,16 @@ fatal_error_signal (int sig)
   /* @r{Now do the clean up actions:}
      @r{- reset terminal modes}
      @r{- kill child processes}
-     @r{- auto save buffers being edited}
      @r{- remove lock files} */
   @dots{}
 @end group
 
 @group
-  /* @r{Now resend the signal.  Since we set the handling for it back to}
-     @r{its default, this will cause the program to terminate.  We could}
-     @r{just call @code{exit} or @code{abort} here, but resending the signal}
-     @r{will set the return status from the process correctly.} */
+  /* @r{Now reraise the signal.  Since the signal is blocked,}
+     @r{it will receive its default handling, which is}
+     @r{to terminate the process.  We could just call}
+     @r{@code{exit} or @code{abort}, but reraising the signal}
+     @r{sets the return status from the process correctly.} */
   raise (sig);
 @}
 @end group
@@ -2220,9 +2273,10 @@ the @code{kill} function.
 @include sigusr.c.texi
 @end example
 
-@c !!! say: This example uses a busy wait, which is bad.
-There is an example in @ref{Waiting for a Signal} that shows you how
-you can make a program block until a signal arrives.
+This example uses a busy wait, which is bad, because it wastes CPU
+cycles that other programs could otherwise use.  It is better to ask the
+system to wait until the signal arrives.  See the example in
+@ref{Waiting for a Signal}.
 
 @node Blocking Signals
 @section Blocking Signals
@@ -2659,14 +2713,13 @@ void
 update_mumble (int frob)
 @{
   /* @r{Prevent signals from having immediate effect.} */
-  defer_signal = 1;
+  defer_signal++;
   /* @r{Now update @code{mumble}, without worrying about interruption.} */
   mumble.a = 1;
   mumble.b = hack ();
   mumble.c = frob;
   /* @r{We have updated @code{mumble}.  Handle any signal that came in.} */
-@c !!! this used to say `defer_signal--' which is NOT ATOMIC!!!
-  defer_signal = 0;
+  defer_signal--;
   if (defer_signal == 0 && signal_pending != 0)
     raise (signal_pending);
 @}
@@ -2683,6 +2736,13 @@ not only within @code{update_mumble}, but also within the caller.  This
 is also why we do not check @code{signal_pending} if @code{defer_signal}
 is still nonzero.
 
+The incrementing and decrementing of @code{defer_signal} require more
+than one instruction; it is possible for a signal to happen in the
+middle.  But that does not cause any problem.  If the signal happens
+early enough to see the value from before the increment or decrement,
+that is equivalent to a signal which came before the beginning of the
+increment or decrement, which is a case that works properly.
+
 It is absolutely vital to decrement @code{defer_signal} before testing
 @code{signal_pending}, because this avoids a subtle bug.  If we did
 these things in the other order, like this,
@@ -2820,10 +2880,9 @@ run, using @code{sigsuspend}.
 @subsection Using @code{sigsuspend}
 
 The clean and reliable way to wait for a signal to arrive is to block it
-and then use @code{sigsuspend}.  
-This also enables you to wait for certain kinds of signals, while
-letting other kinds of signals be handled by their handlers.
-@c !!! huh?  no, it doesn't.  it returns as soon as the handler runs.
+and then use @code{sigsuspend}.  By using @code{sigsuspend} in a loop,
+you can wait for certain kinds of signals, while letting other kinds of
+signals be handled by their handlers.
 
 @comment signal.h
 @comment POSIX.1
@@ -2845,8 +2904,8 @@ when it returns.
 The return value and error conditions are the same as for @code{pause}.
 @end deftypefun
 
-Here is how to replace the @code{pause} or @code{sleep} loop with
-something completely reliable:
+With @code{sigsuspend}, you can replace the @code{pause} or @code{sleep}
+loop in the previous section with something completely reliable:
 
 @example
 sigset_t mask, oldmask;
@@ -3061,10 +3120,10 @@ signals is restored.
 @node Signal Stack
 @subsection Using a Separate Signal Stack
 
+@c ??? Can we do better than recommending a magic constant size?
 A signal stack is a special area of memory to be used as the execution
 stack during signal handlers.  It should be fairly large, to avoid any
 danger that it will overflow in turn---we recommend at least 16,000
-@c !!! that's a good random number.  how about 17 instead?
 bytes.  You can use @code{malloc} to allocate the space for the stack.
 Then call @code{sigstack} to tell the system to use that space for the
 signal stack.