   This file documents the GNU C library.

   This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of `The GNU C
Library Reference Manual', for Version 2.1 Beta.

   Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software
Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the section entitled "GNU Library General Public License" is
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the text of the translation of the section
entitled "GNU Library General Public License" must be approved for
accuracy by the Foundation.

Program Error Signals
---------------------

   The following signals are generated when a serious program error is
detected by the operating system or the computer itself.  In general,
all of these signals are indications that your program is seriously
broken in some way, and there's usually no way to continue the
computation which encountered the error.

   Some programs handle program error signals in order to tidy up before
terminating; for example, programs that turn off echoing of terminal
input should handle program error signals in order to turn echoing back
on.  The handler should end by specifying the default action for the
signal that happened and then reraising it; this will cause the program
to terminate with that signal, as if it had not had a handler.  (see
Termination in Handler.)

   Termination is the sensible ultimate outcome from a program error in
most programs.  However, programming systems such as Lisp that can load
compiled user programs might need to keep executing even if a user
program incurs an error.  These programs have handlers which use
`longjmp' to return control to the command level.

   The default action for all of these signals is to cause the process
to terminate.  If you block or ignore these signals or establish
handlers for them that return normally, your program will probably
break horribly when such signals happen, unless they are generated by
`raise' or `kill' instead of a real error.

   When one of these program error signals terminates a process, it also
writes a "core dump file" which records the state of the process at the
time of termination.  The core dump file is named `core' and is written
in whichever directory is current in the process at the time.  (On the
GNU system, you can specify the file name for core dumps with the
environment variable `COREFILE'.)  The purpose of core dump files is so
that you can examine them with a debugger to investigate what caused
the error.

 - Macro: int SIGFPE
     The `SIGFPE' signal reports a fatal arithmetic error.  Although the
     name is derived from "floating-point exception", this signal
     actually covers all arithmetic errors, including division by zero
     and overflow.  If a program stores integer data in a location
     which is then used in a floating-point operation, this often
     causes an "invalid operation" exception, because the processor
     cannot recognize the data as a floating-point number.

     Actual floating-point exceptions are a complicated subject because
     there are many types of exceptions with subtly different meanings,
     and the `SIGFPE' signal doesn't distinguish between them.  The
     `IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std
     754-1985 and ANSI/IEEE Std 854-1987)' 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.

   BSD systems provide the `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).

`FPE_INTOVF_TRAP'
     Integer overflow (impossible in a C program unless you enable
     overflow trapping in a hardware-specific fashion).

`FPE_INTDIV_TRAP'
     Integer division by zero.

`FPE_SUBRNG_TRAP'
     Subscript-range (something that C programs never check for).

`FPE_FLTOVF_TRAP'
     Floating overflow trap.

`FPE_FLTDIV_TRAP'
     Floating/decimal division by zero.

`FPE_FLTUND_TRAP'
     Floating underflow trap.  (Trapping on floating underflow is not
     normally enabled.)

`FPE_DECOVF_TRAP'
     Decimal overflow trap.  (Only a few machines have decimal
     arithmetic and C never uses it.)

 - Macro: int SIGILL
     The name of this signal is derived from "illegal instruction"; it
     usually means your program is trying to execute garbage or a
     privileged instruction.  Since the C compiler generates only valid
     instructions, `SIGILL' typically indicates that the executable
     file is corrupted, or that you are trying to execute data.  Some
     common ways of getting into the latter situation are by passing an
     invalid object where a pointer to a function was expected, or by
     writing past the end of an automatic array (or similar problems
     with pointers to automatic variables) and corrupting other data on
     the stack such as the return address of a stack frame.

     `SIGILL' can also be generated when the stack overflows, or when
     the system has trouble running the handler for a signal.

 - Macro: int SIGSEGV
     This signal is generated when a program tries to read or write
     outside the memory that is allocated for it, or to write memory
     that can only be read.  (Actually, the signals only occur when the
     program goes far enough outside to be detected by the system's
     memory protection mechanism.)  The name is an abbreviation for
     "segmentation violation".

     Common ways of getting a `SIGSEGV' condition include dereferencing
     a null or uninitialized pointer, or when you use a pointer to step
     through an array, but fail to check for the end of the array.  It
     varies among systems whether dereferencing a null pointer generates
     `SIGSEGV' or `SIGBUS'.

 - Macro: int SIGBUS
     This signal is generated when an invalid pointer is dereferenced.
     Like `SIGSEGV', this signal is typically the result of
     dereferencing an uninitialized pointer.  The difference between
     the two is that `SIGSEGV' indicates an invalid access to valid
     memory, while `SIGBUS' indicates an access to an invalid address.
     In particular, `SIGBUS' signals often result from dereferencing a
     misaligned pointer, such as referring to a four-word integer at an
     address not divisible by four.  (Each kind of computer has its own
     requirements for address alignment.)

     The name of this signal is an abbreviation for "bus error".

 - Macro: int SIGABRT
     This signal indicates an error detected by the program itself and
     reported by calling `abort'.  See Aborting a Program.

 - Macro: int SIGIOT
     Generated by the PDP-11 "iot" instruction.  On most machines, this
     is just another name for `SIGABRT'.

 - Macro: int SIGTRAP
     Generated by the machine's breakpoint instruction, and possibly
     other trap instructions.  This signal is used by debuggers.  Your
     program will probably only see `SIGTRAP' if it is somehow
     executing bad instructions.

 - Macro: int SIGEMT
     Emulator trap; this results from certain unimplemented instructions
     which might be emulated in software, or the operating system's
     failure to properly emulate them.

 - Macro: int SIGSYS
     Bad system call; that is to say, the instruction to trap to the
     operating system was executed, but the code number for the system
     call to perform was invalid.

Termination Signals
-------------------

   These signals are all used to tell a process to terminate, in one way
or another.  They have different names because they're used for slightly
different purposes, and programs might want to handle them differently.

   The reason for handling these signals is usually so your program can
tidy up as appropriate before actually terminating.  For example, you
might want to save state information, delete temporary files, or restore
the previous terminal modes.  Such a handler should end by specifying
the default action for the signal that happened and then reraising it;
this will cause the program to terminate with that signal, as if it had
not had a handler.  (see Termination in Handler.)

   The (obvious) default action for all of these signals is to cause the
process to terminate.

 - Macro: int SIGTERM
     The `SIGTERM' signal is a generic signal used to cause program
     termination.  Unlike `SIGKILL', this signal can be blocked,
     handled, and ignored.  It is the normal way to politely ask a
     program to terminate.

     The shell command `kill' generates `SIGTERM' by default.

 - Macro: int SIGINT
     The `SIGINT' ("program interrupt") signal is sent when the user
     types the INTR character (normally `C-c').  See Special Characters,
     for information about terminal driver support for
     `C-c'.

 - Macro: int SIGQUIT
     The `SIGQUIT' signal is similar to `SIGINT', except that it's
     controlled by a different key--the QUIT character, usually
     `C-\'--and produces a core dump when it terminates the process,
     just like a program error signal.  You can think of this as a
     program error condition "detected" by the user.

     See Program Error Signals, for information about core dumps.
     See Special Characters, for information about terminal driver
     support.

     Certain kinds of cleanups are best omitted in handling `SIGQUIT'.
     For example, if the program creates temporary files, it should
     handle the other termination requests by deleting the temporary
     files.  But it is better for `SIGQUIT' not to delete them, so that
     the user can examine them in conjunction with the core dump.

 - Macro: int SIGKILL
     The `SIGKILL' signal is used to cause immediate program
     termination.  It cannot be handled or ignored, and is therefore
     always fatal.  It is also not possible to block this signal.

     This signal is usually generated only by explicit request.  Since
     it cannot be handled, you should generate it only as a last
     resort, after first trying a less drastic method such as `C-c' or
     `SIGTERM'.  If a process does not respond to any other termination
     signals, sending it a `SIGKILL' signal will almost always cause it
     to go away.

     In fact, if `SIGKILL' fails to terminate a process, that by itself
     constitutes an operating system bug which you should report.

     The system will generate `SIGKILL' for a process itself under some
     unusual conditions where the program cannot possible continue to
     run (even to run a signal handler).

 - Macro: int SIGHUP
     The `SIGHUP' ("hang-up") signal is used to report that the user's
     terminal is disconnected, perhaps because a network or telephone
     connection was broken.  For more information about this, see
     Control Modes.

     This signal is also used to report the termination of the
     controlling process on a terminal to jobs associated with that
     session; this termination effectively disconnects all processes in
     the session from the controlling terminal.  For more information,
     see Termination Internals.

Alarm Signals
-------------

   These signals are used to indicate the expiration of timers.  See
Setting an Alarm, for information about functions that cause these
signals to be sent.

   The default behavior for these signals is to cause program
termination.  This default is rarely useful, but no other default would
be useful; most of the ways of using these signals would require
handler functions in any case.

 - Macro: int SIGALRM
     This signal typically indicates expiration of a timer that
     measures real or clock time.  It is used by the `alarm' function,
     for example.

 - Macro: int SIGVTALRM
     This signal typically indicates expiration of a timer that
     measures CPU time used by the current process.  The name is an
     abbreviation for "virtual time alarm".

 - Macro: int SIGPROF
     This signal is typically indicates expiration of a timer that
     measures both CPU time used by the current process, and CPU time
     expended on behalf of the process by the system.  Such a timer is
     used to implement code profiling facilities, hence the name of
     this signal.

Asynchronous I/O Signals
------------------------

   The signals listed in this section are used in conjunction with
asynchronous I/O facilities.  You have to take explicit action by
calling `fcntl' to enable a particular file descriptor to generate
these signals (see Interrupt Input).  The default action for these
signals is to ignore them.

 - Macro: int SIGIO
     This signal is sent when a file descriptor is ready to perform
     input or output.

     On most operating systems, terminals and sockets are the only
     kinds of files that can generate `SIGIO'; other kinds, including
     ordinary files, never generate `SIGIO' even if you ask them to.

     In the GNU system `SIGIO' will always be generated properly if you
     successfully set asynchronous mode with `fcntl'.

 - Macro: int SIGURG
     This signal is sent when "urgent" or out-of-band data arrives on a
     socket.  See Out-of-Band Data.

 - Macro: int SIGPOLL
     This is a System V signal name, more or less similar to `SIGIO'.
     It is defined only for compatibility.

Job Control Signals
-------------------

   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.

   You should generally leave these signals alone unless you really
understand how job control works.  See Job Control.

 - Macro: int SIGCHLD
     This signal is sent to a parent process whenever one of its child
     processes terminates or stops.

     The default action for this signal is to ignore it.  If you
     establish a handler for this signal while there are child
     processes that have terminated but not reported their status via
     `wait' or `waitpid' (see Process Completion), whether your new
     handler applies to those processes or not depends on the
     particular operating system.

 - Macro: int SIGCLD
     This is an obsolete name for `SIGCHLD'.

 - Macro: int SIGCONT
     You can send a `SIGCONT' signal to a process to make it continue.
     This signal is special--it always makes the process continue if it
     is stopped, before the signal is delivered.  The default behavior
     is to do nothing else.  You cannot block this signal.  You can set
     a handler, but `SIGCONT' always makes the process continue
     regardless.

     Most programs have no reason to handle `SIGCONT'; they simply
     resume execution without realizing they were ever stopped.  You
     can use a handler for `SIGCONT' to make a program do something
     special when it is stopped and continued--for example, to reprint
     a prompt when it is suspended while waiting for input.

 - Macro: int SIGSTOP
     The `SIGSTOP' signal stops the process.  It cannot be handled,
     ignored, or blocked.

 - Macro: int SIGTSTP
     The `SIGTSTP' signal is an interactive stop signal.  Unlike
     `SIGSTOP', this signal can be handled and ignored.

     Your program should handle this signal if you have a special need
     to leave files or system tables in a secure state when a process is
     stopped.  For example, programs that turn off echoing should handle
     `SIGTSTP' so they can turn echoing back on before stopping.

     This signal is generated when the user types the SUSP character
     (normally `C-z').  For more information about terminal driver
     support, see Special Characters.

 - Macro: int SIGTTIN
     A process cannot read from the user's terminal while it is running
     as a background job.  When any process in a background job tries to
     read from the terminal, all of the processes in the job are sent a
     `SIGTTIN' signal.  The default action for this signal is to stop
     the process.  For more information about how this interacts with
     the terminal driver, see Access to the Terminal.

 - Macro: int SIGTTOU
     This is similar to `SIGTTIN', but is generated when a process in a
     background job attempts to write to the terminal or set its modes.
     Again, the default action is to stop the process.  `SIGTTOU' is
     only generated for an attempt to write to the terminal if the
     `TOSTOP' output mode is set; see Output Modes.

   While a process is stopped, no more signals can be delivered to it
until it is continued, except `SIGKILL' signals and (obviously)
`SIGCONT' signals.  The signals are marked as pending, but not
delivered until the process is continued.  The `SIGKILL' signal always
causes termination of the process and can't be blocked, handled or
ignored.  You can ignore `SIGCONT', but it always causes the process to
be continued anyway if it is stopped.  Sending a `SIGCONT' signal to a
process causes any pending stop signals for that process to be
discarded.  Likewise, any pending `SIGCONT' signals for a process are
discarded when it receives a stop signal.

   When a process in an orphaned process group (see Orphaned Process Groups)
receives a `SIGTSTP', `SIGTTIN', or `SIGTTOU' signal and does
not handle it, the process does not stop.  Stopping the process would
probably not be very useful, since there is no shell program that will
notice it stop and allow the user to continue it.  What happens instead
depends on the operating system you are using.  Some systems may do
nothing; others may deliver another signal instead, such as `SIGKILL'
or `SIGHUP'.  In the GNU system, the process dies with `SIGKILL'; this
avoids the problem of many stopped, orphaned processes lying around the
system.

Operation Error Signals
-----------------------

   These signals are used to report various errors generated by an
operation done by the program.  They do not necessarily indicate a
programming error in the program, but an error that prevents an
operating system call from completing.  The default action for all of
them is to cause the process to terminate.

 - Macro: int SIGPIPE
     Broken pipe.  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, writing to the pipe or FIFO raises a
     `SIGPIPE' signal.  If `SIGPIPE' is blocked, handled or ignored,
     the offending call fails with `EPIPE' instead.

     Pipes and FIFO special files are discussed in more detail in
     Pipes and FIFOs.

     Another cause of `SIGPIPE' is when you try to output to a socket
     that isn't connected.  See Sending Data.

 - Macro: int SIGLOST
     Resource lost.  This signal is generated when you have an advisory
     lock on an NFS file, and the NFS server reboots and forgets about
     your lock.

     In the GNU system, `SIGLOST' is generated when any server program
     dies unexpectedly.  It is usually fine to ignore the signal;
     whatever call was made to the server that died just returns an
     error.

 - Macro: int SIGXCPU
     CPU time limit exceeded.  This signal is generated when the process
     exceeds its soft resource limit on CPU time.  See Limits on Resources.

 - Macro: int SIGXFSZ
     File size limit exceeded.  This signal is generated when the
     process attempts to extend a file so it exceeds the process's soft
     resource limit on file size.  See Limits on Resources.

Miscellaneous Signals
---------------------

   These signals are used for various other purposes.  In general, they
will not affect your program unless it explicitly uses them for
something.

 - Macro: int SIGUSR1
 - Macro: int SIGUSR2
     The `SIGUSR1' and `SIGUSR2' signals are set aside for you to use
     any way you want.  They're useful for simple interprocess
     communication, if you write a signal handler for them in the
     program that receives the signal.

     There is an example showing the use of `SIGUSR1' and `SIGUSR2' in
     Signaling Another Process.

     The default action is to terminate the process.

 - Macro: int SIGWINCH
     Window size change.  This is generated on some systems (including
     GNU) when the terminal driver's record of the number of rows and
     columns on the screen is changed.  The default action is to ignore
     it.

     If a program does full-screen display, it should handle `SIGWINCH'.
     When the signal arrives, it should fetch the new screen size and
     reformat its display accordingly.

 - Macro: int SIGINFO
     Information request.  In 4.4 BSD and the GNU system, this signal
     is sent to all the processes in the foreground process group of
     the controlling terminal when the user types the STATUS character
     in canonical mode; see Signal Characters.

     If the process is the leader of the process group, the default
     action is to print some status information about the system and
     what the process is doing.  Otherwise the default is to do nothing.

Signal Messages
---------------

   We mentioned above that the shell prints a message describing the
signal that terminated a child process.  The clean way to print a
message describing a signal is to use the functions `strsignal' and
`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 (see Process Completion) or it may come
from a signal handler in the same process.

 - Function: char * strsignal (int SIGNUM)
     This function returns a pointer to a statically-allocated string
     containing a message describing the signal SIGNUM.  You should not
     modify the contents of this string; and, since it can be rewritten
     on subsequent calls, you should save a copy of it if you need to
     reference it later.

     This function is a GNU extension, declared in the header file
     `string.h'.

 - Function: void psignal (int SIGNUM, const char *MESSAGE)
     This function prints a message describing the signal SIGNUM to the
     standard error output stream `stderr'; see Standard Streams.

     If you call `psignal' with a MESSAGE that is either a null pointer
     or an empty string, `psignal' just prints the message
     corresponding to SIGNUM, adding a trailing newline.

     If you supply a non-null MESSAGE argument, then `psignal' prefixes
     its output with this string.  It adds a colon and a space
     character to separate the MESSAGE from the string corresponding to
     SIGNUM.

     This function is a BSD feature, declared in the header file
     `signal.h'.

   There is also an array `sys_siglist' which contains the messages for
the various signal codes.  This array exists on BSD systems, unlike
`strsignal'.

Specifying Signal Actions
=========================

   The simplest way to change the action for a signal is to use the
`signal' function.  You can specify a built-in action (such as to
ignore the signal), or you can "establish a handler".

   The GNU library also implements the more versatile `sigaction'
facility.  This section describes both facilities and gives suggestions
on which to use when.

Basic Signal Handling
---------------------

   The `signal' function provides a simple interface for establishing
an action for a particular signal.  The function and associated macros
are declared in the header file `signal.h'.

 - Data Type: sighandler_t
     This is the type of signal handler functions.  Signal handlers
     take one integer argument specifying the signal number, and have
     return type `void'.  So, you should define handler functions like
     this:

          void HANDLER (int `signum') { ... }

     The name `sighandler_t' for this data type is a GNU extension.

 - Function: sighandler_t signal (int SIGNUM, sighandler_t ACTION)
     The `signal' function establishes ACTION as the action for the
     signal SIGNUM.

     The first argument, SIGNUM, identifies the signal whose behavior
     you want to control, and should be a signal number.  The proper
     way to specify a signal number is with one of the symbolic signal
     names (see Standard Signals)--don't use an explicit number,
     because the numerical code for a given kind of signal may vary
     from operating system to operating system.

     The second argument, ACTION, specifies the action to use for the
     signal SIGNUM.  This can be one of the following:

    `SIG_DFL'
          `SIG_DFL' specifies the default action for the particular
          signal.  The default actions for various kinds of signals are
          stated in Standard Signals.

    `SIG_IGN'
          `SIG_IGN' specifies that the signal should be ignored.

          Your program generally should not ignore signals that
          represent serious events or that are normally used to request
          termination.  You cannot ignore the `SIGKILL' or `SIGSTOP'
          signals at all.  You can ignore program error signals like
          `SIGSEGV', but ignoring the error won't enable the program to
          continue executing meaningfully.  Ignoring user requests such
          as `SIGINT', `SIGQUIT', and `SIGTSTP' is unfriendly.

          When you do not wish signals to be delivered during a certain
          part of the program, the thing to do is to block them, not
          ignore them.  See Blocking Signals.

    `HANDLER'
          Supply the address of a handler function in your program, to
          specify running this handler as the way to deliver the signal.

          For more information about defining signal handler functions,
          see Defining Handlers.

     If you set the action for a signal to `SIG_IGN', or if you set it
     to `SIG_DFL' and the default action is to ignore that signal, then
     any pending signals of that type are discarded (even if they are
     blocked).  Discarding the pending signals means that they will
     never be delivered, not even if you subsequently specify another
     action and unblock this kind of signal.

     The `signal' function returns the action that was previously in
     effect for the specified SIGNUM.  You can save this value and
     restore it later by calling `signal' again.

     If `signal' can't honor the request, it returns `SIG_ERR' instead.
     The following `errno' error conditions are defined for this
     function:

    `EINVAL'
          You specified an invalid SIGNUM; or you tried to ignore or
          provide a handler for `SIGKILL' or `SIGSTOP'.

   *Compatibility Note:* A problem when working with the `signal'
function is that it has a different semantic on BSD and SVID system.
The difference is that on SVID systems the signal handler is
deinstalled after an signal was delivered.  On BSD systems the handler
must be explicitly deinstalled.  In the GNU C Library we use the BSD
version by default.  To use the SVID version you can either use the
function `sysv_signal' (see below) or use the `_XOPEN_SOURCE' feature
select macro (see Feature Test Macros).  Generally it should be
avoided to use this functions due to the compatibility problems.  It is
better to use `sigaction' if it is available since the results are much
more reliable.

   Here is a simple example of setting up a handler to delete temporary
files when certain fatal signals happen:

     #include <signal.h>

     void
     termination_handler (int signum)
     {
       struct temp_file *p;

       for (p = temp_file_list; p; p = p->next)
         unlink (p->name);
     }

     int
     main (void)
     {
       ...
       if (signal (SIGINT, termination_handler) == SIG_IGN)
         signal (SIGINT, SIG_IGN);
       if (signal (SIGHUP, termination_handler) == SIG_IGN)
         signal (SIGHUP, SIG_IGN);
       if (signal (SIGTERM, termination_handler) == SIG_IGN)
         signal (SIGTERM, SIG_IGN);
       ...
     }

Note how if a given signal was previously set to be ignored, this code
avoids altering that setting.  This is because non-job-control shells
often ignore certain signals when starting children, and it is important
for the children to respect this.

   We do not handle `SIGQUIT' or the program error signals in this
example because these are designed to provide information for debugging
(a core dump), and the temporary files may give useful information.

 - Function: sighandler_t sysv_signal (int SIGNUM, sighandler_t ACTION)
     The `sysv_signal' implements the behaviour of the standard
     `signal' function as found on SVID systems.  The difference to BSD
     systems is that the handler is deinstalled after a delivery of a
     signal.

     *Compatibility Note:* As said above for `signal', this function
     should be avoided when possible.  `sigaction' is the preferred
     method.

 - Function: sighandler_t ssignal (int SIGNUM, sighandler_t ACTION)
     The `ssignal' function does the same thing as `signal'; it is
     provided only for compatibility with SVID.

 - Macro: sighandler_t SIG_ERR
     The value of this macro is used as the return value from `signal'
     to indicate an error.

Advanced Signal Handling
------------------------

   The `sigaction' function has the same basic effect as `signal': to
specify how a signal should be handled by the process.  However,
`sigaction' offers more control, at the expense of more complexity.  In
particular, `sigaction' allows you to specify additional flags to
control when the signal is generated and how the handler is invoked.

   The `sigaction' function is declared in `signal.h'.

 - Data Type: struct sigaction
     Structures of type `struct sigaction' are used in the `sigaction'
     function to specify all the information about how to handle a
     particular signal.  This structure contains at least the following
     members:

    `sighandler_t sa_handler'
          This is used in the same way as the ACTION argument to the
          `signal' function.  The value can be `SIG_DFL', `SIG_IGN', or
          a function pointer.  See Basic Signal Handling.

    `sigset_t sa_mask'
          This specifies a set of signals to be blocked while the
          handler runs.  Blocking is explained in Blocking for Handler.
          Note that the signal that was delivered is
          automatically blocked by default before its handler is
          started; this is true regardless of the value in `sa_mask'.
          If you want that signal not to be blocked within its handler,
          you must write code in the handler to unblock it.

    `int sa_flags'
          This specifies various flags which can affect the behavior of
          the signal.  These are described in more detail in
          Flags for Sigaction.

 - Function: int sigaction (int SIGNUM, const struct sigaction *ACTION,
          struct sigaction *OLD-ACTION)
     The ACTION argument is used to set up a new action for the signal
     SIGNUM, while the OLD-ACTION argument is used to return
     information about the action previously associated with this
     symbol.  (In other words, OLD-ACTION has the same purpose as the
     `signal' function's return value--you can check to see what the
     old action in effect for the signal was, and restore it later if
     you want.)

     Either ACTION or OLD-ACTION can be a null pointer.  If OLD-ACTION
     is a null pointer, this simply suppresses the return of
     information about the old action.  If ACTION is a null pointer,
     the action associated with the signal SIGNUM is unchanged; this
     allows you to inquire about how a signal is being handled without
     changing that handling.

     The return value from `sigaction' is zero if it succeeds, and `-1'
     on failure.  The following `errno' error conditions are defined
     for this function:

    `EINVAL'
          The SIGNUM argument is not valid, or you are trying to trap
          or ignore `SIGKILL' or `SIGSTOP'.

Interaction of `signal' and `sigaction'
---------------------------------------

   It's possible to use both the `signal' and `sigaction' functions
within a single program, but you have to be careful because they can
interact in slightly strange ways.

   The `sigaction' function specifies more information than the
`signal' function, so the return value from `signal' cannot express the
full range of `sigaction' possibilities.  Therefore, if you use
`signal' to save and later reestablish an action, it may not be able to
reestablish properly a handler that was established with `sigaction'.

   To avoid having problems as a result, always use `sigaction' to save
and restore a handler if your program uses `sigaction' at all.  Since
`sigaction' is more general, it can properly save and reestablish any
action, regardless of whether it was established originally with
`signal' or `sigaction'.

   On some systems if you establish an action with `signal' and then
examine it with `sigaction', the handler address that you get may not
be the same as what you specified with `signal'.  It may not even be
suitable for use as an action argument with `signal'.  But you can rely
on using it as an argument to `sigaction'.  This problem never happens
on the GNU system.

   So, you're better off using one or the other of the mechanisms
consistently within a single program.

   *Portability Note:* The basic `signal' function is a feature of
ISO C, while `sigaction' is part of the POSIX.1 standard.  If you are
concerned about portability to non-POSIX systems, then you should use
the `signal' function instead.

`sigaction' Function Example
----------------------------

   In Basic Signal Handling, we gave an example of establishing
a simple handler for termination signals using `signal'.  Here is an
equivalent example using `sigaction':

     #include <signal.h>

     void
     termination_handler (int signum)
     {
       struct temp_file *p;

       for (p = temp_file_list; p; p = p->next)
         unlink (p->name);
     }

     int
     main (void)
     {
       ...
       struct sigaction new_action, old_action;

       /* Set up the structure to specify the new action. */
       new_action.sa_handler = termination_handler;
       sigemptyset (&new_action.sa_mask);
       new_action.sa_flags = 0;

       sigaction (SIGINT, NULL, &old_action);
       if (old_action.sa_handler != SIG_IGN)
         sigaction (SIGINT, &new_action, NULL);
       sigaction (SIGHUP, NULL, &old_action);
       if (old_action.sa_handler != SIG_IGN)
         sigaction (SIGHUP, &new_action, NULL);
       sigaction (SIGTERM, NULL, &old_action);
       if (old_action.sa_handler != SIG_IGN)
         sigaction (SIGTERM, &new_action, NULL);
       ...
     }

   The program just loads the `new_action' structure with the desired
parameters and passes it in the `sigaction' call.  The usage of
`sigemptyset' is described later; see Blocking Signals.

   As in the example using `signal', we avoid handling signals
previously set to be ignored.  Here we can avoid altering the signal
handler even momentarily, by using the feature of `sigaction' that lets
us examine the current action without specifying a new one.

   Here is another example.  It retrieves information about the current
action for `SIGINT' without changing that action.

     struct sigaction query_action;

     if (sigaction (SIGINT, NULL, &query_action) < 0)
       /* `sigaction' returns -1 in case of error. */
     else if (query_action.sa_handler == SIG_DFL)
       /* `SIGINT' is handled in the default, fatal manner. */
     else if (query_action.sa_handler == SIG_IGN)
       /* `SIGINT' is ignored. */
     else
       /* A programmer-defined signal handler is in effect. */

Flags for `sigaction'
---------------------

   The `sa_flags' member of the `sigaction' structure is a catch-all
for special features.  Most of the time, `SA_RESTART' is a good value
to use for this field.

   The value of `sa_flags' is interpreted as a bit mask.  Thus, you
should choose the flags you want to set, OR those flags together, and
store the result in the `sa_flags' member of your `sigaction' structure.

   Each signal number has its own set of flags.  Each call to
`sigaction' affects one particular signal number, and the flags that
you specify apply only to that particular signal.

   In the GNU C library, establishing a handler with `signal' sets all
the flags to zero except for `SA_RESTART', whose value depends on the
settings you have made with `siginterrupt'.  See Interrupted Primitives,
to see what this is about.

   These macros are defined in the header file `signal.h'.

 - Macro: int SA_NOCLDSTOP
     This flag is meaningful only for the `SIGCHLD' signal.  When the
     flag is set, the system delivers the signal for a terminated child
     process but not for one that is stopped.  By default, `SIGCHLD' is
     delivered for both terminated children and stopped children.

     Setting this flag for a signal other than `SIGCHLD' has no effect.

 - Macro: int SA_ONSTACK
     If this flag is set for a particular signal number, the system
     uses the signal stack when delivering that kind of signal.  See
     Signal Stack.  If a signal with this flag arrives and you have
     not set a signal stack, the system terminates the program with
     `SIGILL'.

 - Macro: int SA_RESTART
     This flag controls what happens when a signal is delivered during
     certain primitives (such as `open', `read' or `write'), and the
     signal handler returns normally.  There are two alternatives: the
     library function can resume, or it can return failure with error
     code `EINTR'.

     The choice is controlled by the `SA_RESTART' flag for the
     particular kind of signal that was delivered.  If the flag is set,
     returning from a handler resumes the library function.  If the
     flag is clear, returning from a handler makes the function fail.
     See Interrupted Primitives.

Initial Signal Actions
----------------------

   When a new process is created (see Creating a Process), it
inherits handling of signals from its parent process.  However, when
you load a new process image using the `exec' function (see Executing a File),
any signals that you've defined your own handlers for revert
to their `SIG_DFL' handling.  (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.)  Of course, the new program can establish its own
handlers.

   When a program is run by a shell, the shell normally sets the initial
actions for the child process to `SIG_DFL' or `SIG_IGN', as
appropriate.  It's a good idea to check to make sure that the shell has
not set up an initial action of `SIG_IGN' before you establish your own
signal handlers.

   Here is an example of how to establish a handler for `SIGHUP', but
not if `SIGHUP' is currently ignored:

     ...
     struct sigaction temp;

     sigaction (SIGHUP, NULL, &temp);

     if (temp.sa_handler != SIG_IGN)
       {
         temp.sa_handler = handle_sighup;
         sigemptyset (&temp.sa_mask);
         sigaction (SIGHUP, &temp, NULL);
       }

Defining Signal Handlers
========================

   This section describes how to write a signal handler function that
can be established with the `signal' or `sigaction' functions.

   A signal handler is just a function that you compile together with
the rest of the program.  Instead of directly invoking the function,
you use `signal' or `sigaction' to tell the operating system to call it
when a signal arrives.  This is known as "establishing" the handler.
See Signal Actions.

   There are two basic strategies you can use in signal handler
functions:

   * You can have the handler function note that the signal arrived by
     tweaking some global data structures, and then return normally.

   * You can have the handler function terminate the program or transfer
     control to a point where it can recover from the situation that
     caused the signal.

   You need to take special care in writing handler functions because
they can be called asynchronously.  That is, a handler might be called
at any point in the program, unpredictably.  If two signals arrive
during a very short interval, one handler can run within another.  This
section describes what your handler should do, and what you should
avoid.

Signal Handlers that Return
---------------------------

   Handlers which return normally are usually used for signals such as
`SIGALRM' and the I/O and interprocess communication signals.  But a
handler for `SIGINT' might also return normally after setting a flag
that tells the program to exit at a convenient time.

   It is not safe to return normally from the handler for a program
error signal, because the behavior of the program when the handler
function returns is not defined after a program error.  See Program Error Signals.

   Handlers that return normally must modify some global variable in
order to have any effect.  Typically, the variable is one that is
examined periodically by the program during normal operation.  Its data
type should be `sig_atomic_t' for reasons described in Atomic Data Access.

   Here is a simple example of such a program.  It executes the body of
the loop until it has noticed that a `SIGALRM' signal has arrived.
This technique is useful because it allows the iteration in progress
when the signal arrives to complete before the loop exits.

     #include <signal.h>
     #include <stdio.h>
     #include <stdlib.h>

     /* This flag controls termination of the main loop. */
     volatile sig_atomic_t keep_going = 1;

     /* The signal handler just clears the flag and re-enables itself. */
     void
     catch_alarm (int sig)
     {
       keep_going = 0;
       signal (sig, catch_alarm);
     }

     void
     do_stuff (void)
     {
       puts ("Doing stuff while waiting for alarm....");
     }

     int
     main (void)
     {
       /* Establish a handler for SIGALRM signals. */
       signal (SIGALRM, catch_alarm);

       /* Set an alarm to go off in a little while. */
       alarm (2);

       /* Check the flag once in a while to see when to quit. */
       while (keep_going)
         do_stuff ();

       return EXIT_SUCCESS;
     }

Handlers That Terminate the Process
-----------------------------------

   Handler functions that terminate the program are typically used to
cause 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.  Here is how
to do this:

     volatile sig_atomic_t fatal_error_in_progress = 0;

     void
     fatal_error_signal (int sig)
     {
       /* Since this handler is established for more than one kind of signal,
          it might still get invoked recursively by delivery of some other kind
          of signal.  Use a static variable to keep track of that. */
       if (fatal_error_in_progress)
         raise (sig);
       fatal_error_in_progress = 1;

       /* Now do the clean up actions:
          - reset terminal modes
          - kill child processes
          - remove lock files */
       ...

       /* Now reraise the signal.  We reactivate the signal's
          default handling, which is to terminate the process.
          We could just call `exit' or `abort',
          but reraising the signal sets the return status
          from the process correctly. */
       signal (sig, SIG_DFL);
       raise (sig);
     }

Nonlocal Control Transfer in Handlers
-------------------------------------

   You can do a nonlocal transfer of control out of a signal handler
using the `setjmp' and `longjmp' facilities (see Non-Local Exits).

   When the handler does a nonlocal control transfer, the part of the
program that was running will not continue.  If this part of the program
was in the middle of updating an important data structure, the data
structure will remain inconsistent.  Since the program does not
terminate, the inconsistency is likely to be noticed later on.

   There are two ways to avoid this problem.  One is to block the signal
for the parts of the program that update important data structures.
Blocking the signal delays its delivery until it is unblocked, once the
critical updating is finished.  See Blocking Signals.

   The other way to re-initialize the crucial data structures in the
signal handler, or make their values consistent.

   Here is a rather schematic example showing the reinitialization of
one global variable.

     #include <signal.h>
     #include <setjmp.h>

     jmp_buf return_to_top_level;

     volatile sig_atomic_t waiting_for_input;

     void
     handle_sigint (int signum)
     {
       /* We may have been waiting for input when the signal arrived,
          but we are no longer waiting once we transfer control. */
       waiting_for_input = 0;
       longjmp (return_to_top_level, 1);
     }

     int
     main (void)
     {
       ...
       signal (SIGINT, sigint_handler);
       ...
       while (1) {
         prepare_for_command ();
         if (setjmp (return_to_top_level) == 0)
           read_and_execute_command ();
       }
     }

     /* Imagine this is a subroutine used by various commands. */
     char *
     read_data ()
     {
       if (input_from_terminal) {
         waiting_for_input = 1;
         ...
         waiting_for_input = 0;
       } else {
         ...
       }
     }