Miscellaneous corrections after 1st proofreading.
authorroland <roland>
Tue, 20 Oct 1992 02:01:45 +0000 (02:01 +0000)
committerroland <roland>
Tue, 20 Oct 1992 02:01:45 +0000 (02:01 +0000)
Also added many comments with !!! marking problem spots.

manual/arith.texi
manual/job.texi
manual/signal.texi
manual/startup.texi

index 94455fa..48fc9a9 100644 (file)
@@ -35,6 +35,7 @@ One noteworthy property of NaNs is that they are not equal to
 themselves.  Thus, @code{x == x} can be 0 if the value of @code{x} is a
 NaN.  In fact, this is the way to test whether a value is a NaN or not:
 if it is not equal to itself, then it is a NaN.
+@c !!! should use isnan
 
 Almost any arithmetic operation in which one argument is a NaN returns
 a NaN.
@@ -110,8 +111,8 @@ These functions are provided for obtaining the @dfn{absolute value} (or
 @dfn{magnitude}) of a number.  The absolute value of a real number
 @var{x} is @var{x} is @var{x} is positive, @minus{}@var{x} if @var{x} is
 negative.  For a complex number @var{z}, whose real part is @var{x} and
-whose imaginary part is @var{y}, the absolute value is @code{sqrt
-(@var{x}*@var{x} + @var{y}*@var{y})}.
+whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt
+(@var{x}*@var{x} + @var{y}*@var{y})}}.
 
 @pindex math.h
 @pindex stdlib.h
@@ -125,7 +126,7 @@ This function returns the absolute value of @var{number}.
 
 Most computers use a two's complement integer representation, in which
 the absolute value of @code{INT_MIN} (the smallest possible @code{int})
-cannot be represented; thus, @code{abs (INT_MIN)} is not defined.
+cannot be represented; thus, @w{@code{abs (INT_MIN)}} is not defined.
 @end deftypefun
 
 @comment stdlib.h
@@ -301,10 +302,10 @@ returns @code{0.5} and stores @code{2.0} into @code{intpart}.
 @deftypefun double fmod (double @var{numerator}, double @var{denominator})
 This function computes the remainder of dividing @var{numerator} by
 @var{denominator}.  Specifically, the return value is
-@code{@var{numerator} - @var{n} * @var{denominator}}, where @var{n} is
-the quotient of @var{numerator} by @var{denominator}, rounded towards
-zero to an integer.  Thus, @code{fmod (6.5, 2.3)} returns @code{1.9},
-which is @code{6.5} minus @code{4.6}.
+@w{@code{@var{numerator} - @var{n} * @var{denominator}}}, where @var{n}
+is the quotient of @var{numerator} divided by @var{denominator}, rounded
+towards zero to an integer.  Thus, @w{@code{fmod (6.5, 2.3)}} returns
+@code{1.9}, which is @code{6.5} minus @code{4.6}.
 
 The result has the same sign as the @var{numerator} and has magnitude
 less than the magnitude of the @var{denominator}.
@@ -582,6 +583,8 @@ An optional plus or minus sign (@samp{+} or @samp{-}).
 @item
 A nonempty sequence of digits optionally containing a decimal-point
 character (@samp{.}).
+@c !!! what the decimal point char is varies with locale;
+@c localeconv()->decimal_point tells you.
 
 @item
 An optional exponent part, consisting of a character @samp{e} or
index df688a1..5772f53 100644 (file)
@@ -44,8 +44,8 @@ you explicitly request several programs in their own processes.  But
 even if you run just one program, it can use multiple processes
 internally.  For example, a single compilation command such as @samp{cc
 -c foo.c} typically uses four processes (though normally only two at any
-given time).  If you run Make, its job is to run other programs in
-separate processes.
+given time).  If you run @code{make}, its job is to run other programs
+in separate processes.
 
 The processes belonging to a single command are called a @dfn{process
 group} or @dfn{job}.  This is so that you can operate on all of them at
@@ -113,8 +113,10 @@ whether the system supports job control.  @xref{System Options}.
 
 If job control is not supported, then there can be only one process
 group per session, which behaves as if it were always in the foreground.
-The functions for creating additional process groups simply fail.  The
-macros naming the various job control signals (@pxref{Job Control
+The functions for creating additional process groups simply fail with
+the error code @code{ENOSYS}.
+@c !!! no, SIG* macros are not defined on all systems
+The macros naming the various job control signals (@pxref{Job Control
 Signals}) are defined even if job control is not supported.  However,
 the system never generates these signals, and attempts to send a job
 control signal or examine or specify their actions report errors or do
@@ -141,6 +143,7 @@ An individual process disconnects from its controlling terminal when it
 calls @code{setsid} to become the leader of a new session.
 @xref{Process Group Functions}.
 
+@c !!! explain how it gets a new one (by opening any terminal)
 
 @node Access to the Terminal, Orphaned Process Groups, Controlling Terminal, Job Control
 @section Access to the Controlling Terminal
@@ -157,17 +160,17 @@ terminal, the process group is usually sent a @code{SIGTTIN} signal.
 This normally causes all of the processes in that group to stop (unless
 they handle the signal and don't stop themselves).  However, if the
 reading process is ignoring or blocking this signal, then @code{read}
-fails with a @code{EIO} error instead.
+fails with an @code{EIO} error instead.
 
 @cindex @code{SIGTTOU}, from background job
 Similarly, when a process in a background job tries to write to its
-controlling terminal, the default behavior is to send a @code{SIGTTOU} 
+controlling terminal, the default behavior is to send a @code{SIGTTOU}
 signal to the process group.  However, the behavior is modified by the
 @code{TOSTOP} bit of the local modes flags (@pxref{Local Modes}).  If
-this bit is not set, then writing to the controlling terminal is always
-permitted without sending a signal.  Writing is also permitted if the
-@code{SIGTTOU} signal is being ignored or blocked by the writing
-process.
+this bit is not set (which is the default), then writing to the
+controlling terminal is always permitted without sending a signal.
+Writing is also permitted if the @code{SIGTTOU} signal is being ignored
+or blocked by the writing process.
 
 Most other terminal operations that a program can do are treated as
 reading or as writing.  (The description of each operation should say
@@ -222,7 +225,7 @@ to execute commands.
 
 @item
 @ref{Foreground and Background}, discusses what the shell should
-do differently when launching jobs in the foreground as opposed to
+do differently when launching a job in the foreground as opposed to
 a background job.
 
 @item
@@ -264,9 +267,10 @@ holds information about a single subprocess.  Here are the relevant
 data structure declarations:
 
 @example
+@group
 /* @r{A process is a single process.}  */
-
-typedef struct process @{
+typedef struct process
+@{
   struct process *next;       /* @r{next process in pipeline} */
   char **argv;                /* @r{for exec} */
   pid_t pid;                  /* @r{process ID} */
@@ -274,10 +278,12 @@ typedef struct process @{
   char stopped;               /* @r{true if process has stopped} */
   int status;                 /* @r{reported status value} */
 @} process;
+@end group
 
+@group
 /* @r{A job is a pipeline of processes.}  */
-
-typedef struct job @{
+typedef struct job
+@{
   struct job *next;           /* @r{next active job} */
   char *command;              /* @r{command line, used for messages} */
   process *first_process;     /* @r{list of processes in this job} */
@@ -287,18 +293,17 @@ typedef struct job @{
   int stdin, stdout, stderr;  /* @r{standard i/o channels} */
 @} job;
 
-
 /* @r{The active jobs are linked into a list.  This is its head.}   */
-
 job *first_job = NULL;
+@end group
 @end example
 
 Here are some utility functions that are used for operating on @code{job}
 objects.
 
 @example
+@group
 /* @r{Find the active job with the indicated pgid.}  */
-
 job *
 find_job (pid_t pgid)
 @{
@@ -309,10 +314,10 @@ find_job (pid_t pgid)
       return j;
   return NULL;
 @}
+@end group
 
-
+@group
 /* @r{Return true if all processes in the job have stopped or completed.}  */
-
 int
 job_is_stopped (job *j)
 @{
@@ -323,10 +328,10 @@ job_is_stopped (job *j)
       return 0;
   return 1;
 @}
+@end group
 
-
+@group
 /* @r{Return true if all processes in the job have completed.}  */
-
 int
 job_is_completed (job *j)
 @{
@@ -337,6 +342,7 @@ job_is_completed (job *j)
       return 0;
   return 1;
 @}
+@end group
 @end example
 
 
@@ -389,6 +395,10 @@ do all of this.
 @example
 /* @r{Keep track of attributes of the shell.}  */
 
+#include <sys/types.h>
+#include <termios.h>
+#include <unistd.h>
+
 pid_t shell_pgid;
 struct termios shell_tmodes;
 int shell_terminal;
@@ -406,33 +416,34 @@ init_shell ()
   shell_terminal = STDIN_FILENO;
   shell_is_interactive = isatty (shell_terminal);
 
-  if (shell_is_interactive) @{
-
-    /* @r{Loop until we are in the foreground.}  */
-    while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ()))
-      kill (-shell_pgid, SIGTTIN);
-  
-    /* @r{Ignore interactive and job-control signals.}  */
-    signal (SIGINT, SIG_IGN);
-    signal (SIGQUIT, SIG_IGN);
-    signal (SIGTSTP, SIG_IGN);
-    signal (SIGTTIN, SIG_IGN);
-    signal (SIGTTOU, SIG_IGN);
-    signal (SIGCHLD, SIG_IGN);
-    
-    /* @r{Put ourselves in our own process group.}  */
-    shell_pgid = getpid ();
-    if (setpgid (shell_pgid, shell_pgid) < 0) @{
-      fprintf (stderr, "Couldn't put the shell in its own process group\n");
-      exit (errno);
+  if (shell_is_interactive)
+    @{
+      /* @r{Loop until we are in the foreground.}  */
+      while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ()))
+        kill (- shell_pgid, SIGTTIN);
+
+      /* @r{Ignore interactive and job-control signals.}  */
+      signal (SIGINT, SIG_IGN);
+      signal (SIGQUIT, SIG_IGN);
+      signal (SIGTSTP, SIG_IGN);
+      signal (SIGTTIN, SIG_IGN);
+      signal (SIGTTOU, SIG_IGN);
+      signal (SIGCHLD, SIG_IGN);
+
+      /* @r{Put ourselves in our own process group.}  */
+      shell_pgid = getpid ();
+      if (setpgid (shell_pgid, shell_pgid) < 0)
+        @{
+          perror ("Couldn't put the shell in its own process group");
+          exit (1);
+        @}
+
+      /* @r{Grab control of the terminal.}  */
+      tcsetpgrp (shell_terminal, shell_pgid);
+
+      /* @r{Save default terminal attributes for shell.}  */
+      tcgetattr (shell_terminal, &shell_tmodes);
     @}
-    
-    /* @r{Grab control of the terminal.}  */
-    tcsetpgrp (shell_terminal, shell_pgid);
-  
-    /* @r{Save default terminal attributes for shell.}  */
-    tcgetattr (shell_terminal, &shell_tmodes);
-  @}
 @}
 @end example
 
@@ -552,8 +563,8 @@ launch_process (process *p, pid_t pgid,
   
   /* @r{Exec the new process.  Make sure we exit.}  */ 
   execvp (p->argv[0], p->argv);
-  perror ("exec");
-  exit (errno);
+  perror ("execvp");
+  exit (1);
 @}
 @end example
 
@@ -582,7 +593,7 @@ launch_job (job *j, int foreground)
     if (p->next) @{
       if (pipe (mypipe) < 0) @{
         perror ("pipe");
-        exit (errno);
+        exit (1);
       @}
       outfile = mypipe[1];
     @}
@@ -594,19 +605,23 @@ launch_job (job *j, int foreground)
     if (pid == 0)
       /* @r{This is the child process.}  */
       launch_process (p, j->pgid, infile, outfile, j->stderr, foreground);
-    else if (pid < 0) @{
-      /* @r{The fork failed.}  */
-      perror ("fork");
-      exit (pid);
-    @}
-    else @{
-      /* @r{This is the parent process.}  */
-      p->pid = pid;
-      if (shell_is_interactive) @{
-        if (!j->pgid) j->pgid = pid;
-        setpgid (pid, j->pgid);
+    else if (pid < 0)
+      @{
+        /* @r{The fork failed.}  */
+        perror ("fork");
+        exit (1);
+      @}
+    else
+      @{
+        /* @r{This is the parent process.}  */
+        p->pid = pid;
+        if (shell_is_interactive)
+          @{
+            if (!j->pgid)
+              j->pgid = pid;
+            setpgid (pid, j->pgid);
+          @}
       @}
-    @}
     
     /* @r{Clean up after pipes.}  */
     if (infile != j->stdin)
@@ -656,11 +671,13 @@ current terminal modes so that it can restore them later if the job is
 continued.  The functions for dealing with terminal modes are
 @code{tcgetattr} and @code{tcsetattr}; these are described in
 @ref{Terminal Modes}.
+@c !!! what about programs like stty that SHOULD frob the modes??
 
 
 Here is the sample shell's function for doing all of this.
 
 @example
+@group
 /* @r{Put job J in the foreground.  If CONT is nonzero,}
    @r{restore the saved terminal modes and send the process group a}
    @r{@code{SIGCONT} signal to wake it up before we block.}  */
@@ -670,13 +687,17 @@ put_job_in_foreground (job *j, int cont)
 @{
   /* @r{Put the job into the foreground.}  */
   tcsetpgrp (shell_terminal, j->pgid);
+@end group
 
+@group
   /* @r{Send the job a continue signal, if necessary.}  */
-  if (cont) @{
-    tcsetattr (shell_terminal, TCSADRAIN, &j->tmodes);
-    if (kill (-j->pgid, SIGCONT) < 0)
-      perror ("kill (SIGCONT)");
-  @}
+  if (cont)
+    @{
+      tcsetattr (shell_terminal, TCSADRAIN, &j->tmodes);
+      if (kill (- j->pgid, SIGCONT) < 0)
+        perror ("kill (SIGCONT)");
+    @}
+@end group
   
   /* @r{Wait for it to report.}  */
   wait_for_job (j);
@@ -684,10 +705,12 @@ put_job_in_foreground (job *j, int cont)
   /* @r{Put the shell back in the foreground.}  */
   tcsetpgrp (shell_terminal, shell_pgid);
     
+@group
   /* @r{Restore the shell's terminal modes.}  */
   tcgetattr (shell_terminal, &j->tmodes);
   tcsetattr (shell_terminal, TCSADRAIN, &shell_tmodes);
 @}
+@end group
 @end example
 
 @cindex background job, launching
@@ -748,6 +771,7 @@ Here are the parts of the sample shell program that deal with checking
 the status of jobs and reporting the information to the user.
 
 @example
+@group
 /* @r{Store the status of the process PID that was returned by waitpid.}
    @r{Return 0 if all went well, nonzero otherwise.}  */
 
@@ -755,27 +779,34 @@ int
 mark_process_status (pid_t pid, int status)
 @{
   job *j;
-  Process *p;
-
-  if (pid > 0) @{
-    /* @r{Update the record for the process.}  */
-    for (j = first_job; j; j = j->next)
-      for (p = j->first_process; p; p = p->next)
-        if (p->pid == pid) @{
-          p->status = status;
-          if (WIFSTOPPED (status))
-            p->stopped = 1;
-          else @{
-            p->completed = 1;
-            if (WIFSIGNALED (status))
-              fprintf (stderr, "%ld: Terminated by signal %d.\n",
-                       (long)pid, WTERMSIG (p->status));
-          @}
-          return 0;
-         @}
-    fprintf (stderr, "No child process %d.\n", pid);
-    return -1;
-  @}
+  process *p;
+@end group
+
+@group
+  if (pid > 0)
+    @{
+      /* @r{Update the record for the process.}  */
+      for (j = first_job; j; j = j->next)
+        for (p = j->first_process; p; p = p->next)
+          if (p->pid == pid)
+            @{
+              p->status = status;
+              if (WIFSTOPPED (status))
+                p->stopped = 1;
+              else
+                @{
+                  p->completed = 1;
+                  if (WIFSIGNALED (status))
+                    fprintf (stderr, "%d: Terminated by signal %d.\n",
+                             (int) pid, WTERMSIG (p->status));
+                @}
+              return 0;
+             @}
+      fprintf (stderr, "No child process %d.\n", pid);
+      return -1;
+    @}
+@end group
+@group
   else if (pid == 0 || errno == ECHILD)
     /* @r{No processes ready to report.}  */
     return -1;
@@ -785,8 +816,9 @@ mark_process_status (pid_t pid, int status)
     return -1;
   @}
 @}
+@end group
 
-
+@group
 /* @r{Check for processes that have status information available,}
    @r{without blocking.}  */
 
@@ -796,12 +828,13 @@ update_status (void)
   int status;
   pid_t pid;
   
-  do @{
-    pid = waitpid (-1, &status, WUNTRACED|WNOHANG);
-  @} while (!mark_process_status (pid, status));
+  do
+    pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG);
+  while (!mark_process_status (pid, status));
 @}
+@end group
 
-
+@group
 /* @r{Check for processes that have status information available,}
    @r{blocking until all processes in the given job have reported.}  */
 
@@ -811,14 +844,15 @@ wait_for_job (job *j)
   int status;
   pid_t pid;
   
-  do @{
-    pid = waitpid (-1, &status, WUNTRACED);
-  @} while (!mark_process_status (pid, status) 
-           && !job_is_stopped (j) 
-           && !job_is_completed (j));
+  do
+    pid = waitpid (WAIT_ANY, &status, WUNTRACED);
+  while (!mark_process_status (pid, status) 
+         && !job_is_stopped (j) 
+         && !job_is_completed (j));
 @}
+@end group
 
-
+@group
 /* @r{Format information about job status for the user to look at.}  */
 
 void
@@ -826,7 +860,9 @@ format_job_info (job *j, const char *status)
 @{
   fprintf (stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command);
 @}
+@end group
 
+@group
 /* @r{Notify the user about stopped or terminated jobs.}
    @r{Delete terminated jobs from the active job list.}  */
 
@@ -834,57 +870,57 @@ void
 do_job_notification (void)
 @{
   job *j, *jlast, *jnext;
-  Process *p;
+  process *p;
 
   /* @r{Update status information for child processes.}  */
   update_status ();
   
   jlast = NULL;
-  for (j = first_job; j; j = jnext) @{
-    jnext = j->next;
-    
-    /* @r{If all processes have completed, tell the user the job has}
-       @r{completed and delete it from the list of active jobs.}  */
-    if (job_is_completed (j)) @{
-      format_job_info (j, "completed");
-      if (jlast)
-        jlast->next = jnext;
+  for (j = first_job; j; j = jnext)
+    @{
+      jnext = j->next;
+
+      /* @r{If all processes have completed, tell the user the job has}
+         @r{completed and delete it from the list of active jobs.}  */
+      if (job_is_completed (j)) @{
+        format_job_info (j, "completed");
+        if (jlast)
+          jlast->next = jnext;
+        else
+          first_job = jnext;
+        free_job (j);
+      @}
+
+      /* @r{Notify the user about stopped jobs,}
+         @r{marking them so that we won't do this more than once.}  */
+      else if (job_is_stopped (j) && !j->notified) @{
+        format_job_info (j, "stopped");
+        j->notified = 1;
+        jlast = j;
+      @}
+
+      /* @r{Don't say anything about jobs that are still running.}  */
       else
-        first_job = jnext;
-      free_job (j);
+        jlast = j;
     @}
-    
-    /* @r{Notify the user about stopped jobs,}
-       @r{marking them so that we won't do this more than once.}  */
-    else if (job_is_stopped (j) && !j->notified) @{
-      format_job_info (j, "stopped");
-      j->notified = 1;
-      jlast = j;
-    @}
-    
-    /* @r{Don't say anything about jobs that are still running.}  */
-    else
-      jlast = j;
-  @}
 @}
+@end group
 @end example
 
-
 @node Continuing Stopped Jobs, Missing Pieces, Stopped and Terminated Jobs, Implementing a Shell
 @subsection Continuing Stopped Jobs
 
 @cindex stopped jobs, continuing
 The shell can continue a stopped job by sending a @code{SIGCONT} signal
 to its process group.  If the job is being continued in the foreground,
-the shell should first invoke @code{tcsetgrp} first to give the job
-access to the terminal, and restore the saved terminal settings.  After
-continuing a job in the foreground, the shell should wait for the job to
-stop or complete, as if the job had just been launched in the
-foreground.
+the shell should first invoke @code{tcsetpgrp} to give the job access to
+the terminal, and restore the saved terminal settings.  After continuing
+a job in the foreground, the shell should wait for the job to stop or
+complete, as if the job had just been launched in the foreground.
 
 The sample shell program uses the same set of
-functions---@code{put_job_in_foreground} and
-@code{put_job_in_background}---to handle both newly created and
+functions---@w{@code{put_job_in_foreground}} and
+@w{@code{put_job_in_background}}---to handle both newly created and
 continued jobs.  The definitions of these functions were given in
 @ref{Foreground and Background}.  When continuing a stopped job, a
 nonzero value is passed as the @var{cont} argument to ensure that the
@@ -895,7 +931,7 @@ This leaves only a function for updating the shell's internal bookkeeping
 about the job being continued:
 
 @example
-
+@group
 /* @r{Mark a stopped job J as being running again.}  */
 
 void
@@ -907,8 +943,9 @@ mark_job_as_running (job *j)
     p->stopped = 0;
   j->notified = 0;
 @}
+@end group
 
-
+@group
 /* @r{Continue the job J.}  */
 
 void
@@ -920,9 +957,9 @@ continue_job (job *j, int foreground)
   else
     put_job_in_background (j, 1);
 @}
+@end group
 @end example
 
-
 @node Missing Pieces,  , Continuing Stopped Jobs, Implementing a Shell
 @subsection The Missing Pieces
 
@@ -982,6 +1019,7 @@ to job control.
 @subsection Identifying the Controlling Terminal
 @cindex controlling terminal, determining
 
+@c !!! ctermid returns "/dev/tty"; use ttyname to find the real name.
 You can use the @code{ctermid} function to get a file name that
 corresponds to the controlling terminal for the current process.  It is
 not needed often; if you simply wish to open the controlling terminal,
@@ -1027,7 +1065,7 @@ Your program should include the header files @file{sys/types.h} and
 
 @comment unistd.h
 @comment POSIX.1
-@deftypefun pid_t setsid ()
+@deftypefun pid_t setsid (void)
 The @code{setsid} function creates a new session.  The calling process
 becomes the session leader, and is put in a new process group whose
 process group ID is the same as the process ID of that process.  There
@@ -1036,9 +1074,10 @@ process groups in the new session.
 
 This function also makes the calling process have no controlling terminal.
 
-The @code{setsid} function returns the process group ID of the calling
-process if successful.  A return value of @code{-1} indicates an error.
-The following @code{errno} error conditions are defined for this function:
+The @code{setsid} function returns the new process group ID of the
+calling process if successful.  A return value of @code{-1} indicates an
+error.  The following @code{errno} error conditions are defined for this
+function:
 
 @table @code
 @item EPERM
@@ -1062,7 +1101,7 @@ programs with the @code{-lbsd-compat} option to get the BSD definition.@refill
 
 @comment unistd.h
 @comment POSIX.1
-@deftypefn {POSIX.1 Function} pid_t getpgrp ()
+@deftypefn {POSIX.1 Function} pid_t getpgrp (void)
 The POSIX.1 definition of @code{getpgrp} returns the process group ID of
 the calling process.
 @end deftypefn
@@ -1143,7 +1182,7 @@ group associated with the terminal open on descriptor @var{filedes}.
 If there is no foreground process group, the return value is a number
 greater than @code{1} that does not match the process group ID of any
 existing process group.  This can happen if all of the processes in the
-job that was formerly the foreground job have terminated, and not other
+job that was formerly the foreground job have terminated, and no other
 job has yet been moved into the foreground.
 
 In case of an error, a value of @code{-1} is returned.  The
index 4b9059f..d473fe5 100644 (file)
@@ -18,7 +18,7 @@ If you anticipate an event that causes signals, you can define a handler
 function and tell the operating system to run it when that particular
 type of signal arrives.
 
-Finally, one process can send a signal to another process; this allows
+Finally, one process can send a signal to another process; this allows a
 parent process to abort a child, or two related processes to communicate
 and synchronize.
 
@@ -266,6 +266,7 @@ 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
 
 @comment signal.h
 @comment ANSI
@@ -292,6 +293,8 @@ 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
 
 @comment signal.h
@@ -471,9 +474,8 @@ in any case.
 @comment signal.h
 @comment POSIX.1
 @deftypevr Macro int SIGALRM
-This signal typically indicates expiration of a timer that
-measures real or clock time.  It is used by the @code{alarm} function,
-for example.
+This signal typically indicates expiration of a timer that measures real
+or clock time.  It is used by the @code{alarm} function, for example.
 @end deftypevr
 @cindex alarm signal
 
@@ -534,6 +536,7 @@ 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}.
@@ -571,8 +574,8 @@ is suspended while waiting for input.
 @comment signal.h
 @comment POSIX.1
 @deftypevr Macro int SIGSTOP
-The @code{SIGSTOP} signal stops the process.  It cannot be handled or
-ignored.
+The @code{SIGSTOP} signal stops the process.  It cannot be handled,
+ignored, or blocked.
 @end deftypevr
 @cindex stop signal
 
@@ -609,8 +612,8 @@ the terminal driver, see @ref{Access to the Terminal}.
 @comment POSIX.1
 @deftypevr Macro int SIGTTOU
 This is similar to @code{SIGTTIN}, but is generated when a process in a
-background job attempts to write to the terminal.  Again, the default
-action is to stop the process.
+background job attempts to write to the terminal or set its modes.
+Again, the default action is to stop the process.
 @end deftypevr
 @cindex terminal output signal
 
@@ -659,10 +662,15 @@ 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.
 @end deftypevr
 @cindex pipe signal
 @cindex broken pipe signal
 
+@need 245
 @comment signal.h
 @comment POSIX.1
 @deftypevr Macro int SIGUSR1
@@ -755,6 +763,9 @@ message describing a signal is to use the functions @code{strsignal} and
 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
@@ -1146,7 +1157,7 @@ else
 @cindex flags for @code{sigaction}
 @cindex @code{sigaction} flags
 
-This @code{sa_flags} member of the @code{sigaction} structure is a
+The @code{sa_flags} member of the @code{sigaction} structure is a
 catch-all for special features.  Most of the time, @code{SA_RESTART} is
 a good value to use for this field.
 
@@ -1161,7 +1172,7 @@ that you specify apply only to that particular signal.
 
 In the GNU C library, establishing a handler with @code{signal} sets all
 the flags to zero except for @code{SA_RESTART}, whose value depends on
-the setings you have made with @code{siginterrupt}.  @xref{Interrupted
+the settings you have made with @code{siginterrupt}.  @xref{Interrupted
 Primitives}, to see what this is about.
 
 @pindex signal.h
@@ -1226,6 +1237,7 @@ Here is an example of how to establish a handler for @code{SIGHUP}, but
 not if @code{SIGHUP} is currently ignored:
 
 @example
+@group
 @dots{}
 struct sigaction temp;
 
@@ -1237,6 +1249,7 @@ if (temp.sa_handler != SIG_IGN)
     sigemptyset (&temp.sa_mask);
     sigaction (SIGHUP, &temp, NULL);
   @}
+@end group
 @end example
 
 @node Defining Handlers
@@ -1318,7 +1331,7 @@ when the signal arrives to complete before the loop exits.
 @node Termination in Handler
 @subsection Handlers That Terminate the Process
 
-Handler functions terminate the program are typically used to cause
+Handler functions that terminate the program are typically used to cause
 orderly cleanup or recovery from program error signals and interactive
 interrupts.
 
@@ -1333,32 +1346,38 @@ 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}
      @r{of signal.  Use a static variable to keep track of that.} */
-
   if (fatal_error_in_progress)
     raise (sig);
   fatal_error_in_progress = 1;
+@end group
 
+@group
   /* @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.} */
   raise (sig);
 @}
+@end group
 @end example
 
 @node Longjmp in Handler
@@ -1387,6 +1406,7 @@ Here is a rather schematic example showing the reinitialization of one
 global variable.
 
 @example
+@group
 #include <signal.h>
 #include <setjmp.h>
 
@@ -1402,8 +1422,11 @@ handle_sigint (int signum)
   waiting_for_input = 0;
   longjmp (return_to_top_level, 1);
 @}
+@end group
 
-main ()
+@group
+int
+main (void)
 @{
   @dots{}
   signal (SIGINT, sigint_handler);
@@ -1414,7 +1437,9 @@ main ()
       read_and_execute_command ();
   @}
 @}
+@end group
 
+@group
 /* @r{Imagine this is a subroutine used by various commands.} */
 char *
 read_data ()
@@ -1427,6 +1452,7 @@ read_data ()
     @dots{}
   @}
 @}
+@end group
 @end example
 
 
@@ -1784,8 +1810,7 @@ writing.)
 #include <signal.h>
 #include <stdio.h>
 
-struct two_words @{int a, b;@}
-struct two_words memory;
+struct two_words @{ int a, b; @} memory;
 
 void
 handler(int signum)
@@ -1794,10 +1819,11 @@ handler(int signum)
    alarm (1);
 @}
 
+@group
 int
-main ()
+main (void)
 @{
-   static struct two_words zeros=@{0,0@}, ones=@{1,1@};
+   static struct two_words zeros = @{ 0, 0 @}, ones = @{ 1, 1 @};
    signal (SIGALRM, handler);
    memory = zeros;
    alarm (1);
@@ -1807,10 +1833,11 @@ main ()
        memory = ones;
      @}
 @}
+@end group
 @end example
 
 This program fills @code{memory} with zeros, ones, zeros, ones,
-alternating forever; meanwhile, once persecond, the alarm signal handler
+alternating forever; meanwhile, once per second, the alarm signal handler
 prints the current contents.  (Calling @code{printf} in the handler is
 safe in this program because it is certainly not being called outside
 the handler when the signal happens.)
@@ -2030,6 +2057,7 @@ cont_handler (int sig)
   signal (SIGTSTP, tstp_handler);
 @}
 
+@group
 /* @r{Enable both handlers during program initialization.} */
 
 int
@@ -2039,6 +2067,7 @@ main (void)
   signal (SIGTSTP, tstp_handler);
   @dots{}
 @}
+@end group
 @end example
 
 @strong{Portability note:} @code{raise} was invented by the ANSI C
@@ -2094,8 +2123,7 @@ All processes in the same process group as the sender.  The sender
 itself does not receive the signal.
 
 @item @var{pid} < -1
-The process group whose identifier is @minus{} of
-@var{pid}.
+The process group whose identifier is @minus{}@var{pid}.
 
 @item @var{pid} == -1
 If the process is privileged, send the signal to all processes except
@@ -2103,8 +2131,8 @@ for some special system processes.  Otherwise, send the signal to all
 processes with the same effective user ID.
 @end table
 
-A process can send a signal to itself with @code{kill (getpid(),
-@var{signum};}.  If @code{kill} is used by a process to send a signal to
+A process can send a signal to itself with @w{@code{kill (getpid(),
+@var{signum});}}.  If @code{kill} is used by a process to send a signal to
 itself, and the signal is not blocked, then @code{kill} delivers at
 least one signal (which might be some other pending unblocked signal
 instead of the signal @var{signum}) to that process before it returns.
@@ -2139,18 +2167,8 @@ process group @var{pgid}.  This function is provided for compatibility
 with BSD; using @code{kill} to do this is more portable.
 @end deftypefun
 
-As a simple example of @code{kill}, the call:
-
-@example
-kill (getpid (), @var{sig})
-@end example
-
-@noindent
-has the same effect as:
-
-@example
-raise (@var{sig})
-@end example
+As a simple example of @code{kill}, the call @w{@code{kill (getpid (),
+@var{sig})} has the same effect as @w{@code{raise (@var{sig})}}.
 
 @node Permission for kill
 @subsection Permission for using @code{kill}
@@ -2162,7 +2180,7 @@ user.  In typical use, @code{kill} is used to pass signals between
 parent, child, and sibling processes, and in these situations you
 normally do have permission to send signals.  The only common execption
 is when you run a setuid program in a child process; if the program
-chanes its real uid as well as its effective uid, you may not have
+changes its real UID as well as its effective UID, you may not have
 permission to send a signal.  The @code{su} program does this.
 
 Whether a process has permission to send a signal to another process
@@ -2202,11 +2220,7 @@ the @code{kill} function.
 @include sigusr.c.texi
 @end example
 
-Most of the time, the signal is delivered during a @code{sleep}, and
-@code{sleep} returns immediately as a result.  Once in a while, by luck,
-the signal arrives just before @code{sleep} is called.  Then the program
-waits one extra second--an imperfection, but not a serious problem.
-
+@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.
 
@@ -2450,6 +2464,7 @@ leads to undesirable results for signals generated by an actual program
 error (as opposed to signals sent with @code{raise} or @code{kill}).
 This is because your program may be too broken to be able to continue
 executing to a point where the signal is unblocked again.
+@xref{Program Error Signals}.
 @end deftypefun
 
 @node Testing for Delivery
@@ -2477,6 +2492,7 @@ main (void)
   sigemptyset (&block_alarm);
   sigaddset (&block_alarm, SIGALRM);
 
+@group
   while (1)
     @{
       /* @r{Check if a signal has arrived; if so, reset the flag.} */
@@ -2491,6 +2507,7 @@ main (void)
       @dots{}
     @}
 @}
+@end group
 @end example
 
 @node Blocking for Handler
@@ -2610,6 +2627,9 @@ be discarded.  For example, if a @code{SIGINT} signal is pending when
 another @code{SIGINT} signal arrives, your program will probably only
 see one of them when you unblock this signal.
 
+@strong{Portability Note:} The @code{sigpending} function is new in
+POSIX.1.  Older systems have no equivalent facility.
+
 @node Remembering a Signal
 @subsection Remembering a Signal to Act On Later
 
@@ -2639,13 +2659,14 @@ void
 update_mumble (int frob)
 @{
   /* @r{Prevent signals from having immediate effect.} */
-  defer_signal++;
+  defer_signal = 1;
   /* @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.} */
-  defer_signal--;
+@c !!! this used to say `defer_signal--' which is NOT ATOMIC!!!
+  defer_signal = 0;
   if (defer_signal == 0 && signal_pending != 0)
     raise (signal_pending);
 @}
@@ -2673,7 +2694,7 @@ these things in the other order, like this,
 @end example
 
 @noindent
-then a signal arriving in between the if statement and the decrement
+then a signal arriving in between the @code{if} statement and the decrement
 would be effetively ``lost'' for an indefinite amount of time.  The
 handler would merely set @code{defer_signal}, but the program having
 already tested this variable, it would not test the variable again.
@@ -2799,9 +2820,10 @@ 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.
+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.
 
 @comment signal.h
 @comment POSIX.1
@@ -3042,6 +3064,7 @@ signals is restored.
 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.
@@ -3082,3 +3105,5 @@ stack for use by signal handlers.
 
 The return value is @code{0} on success and @code{1} on failure.
 @end deftypefun
+
+@c !!! 4.4 and GNU has a better interface: sigaltstack
index 683b699..0bb3fec 100644 (file)
@@ -101,7 +101,7 @@ Certain options require an argument.  For example, the @samp{-o} command
 of the @code{ld} command requires an argument---an output file name.
 
 @item
-An option and its argument may or may appear as separate tokens.  (In
+An option and its argument may or may not appear as separate tokens.  (In
 other words, the whitespace separating them is optional.)  Thus,
 @samp{-o foo} and @samp{-ofoo} are equivalent.
 
@@ -133,10 +133,10 @@ interpretation is left up to the particular application program.
 
 @cindex long-named options
 GNU adds @dfn{long options} to these conventions.  Long options consist
-of @samp{--} followed by a name made of alphanumeric characters.  Option
-names are typically one to three words long, with hyphens to separate
-words.  Users can abbreviate the option names as long as the
-abbreviations are unique.
+of @samp{--} followed by a name made of alphanumeric characters and
+dashes.  Option names are typically one to three words long, with
+hyphens to separate words.  Users can abbreviate the option names as
+long as the abbreviations are unique.
 
 To specify an argument for a long option, write
 @samp{--@var{name}=@var{value}}.  This syntax enables a long option to
@@ -207,7 +207,7 @@ string can be followed by a colon (@samp{:}) to indicate that it takes a
 required argument.
 
 If the @var{options} argument string begins with a hyphen (@samp{-}), this
-is treated specially.  It permits arguments without an option to be
+is treated specially.  It permits arguments that are not options to be
 returned as if they were associated with option character @samp{\0}.
 
 The @code{getopt} function returns the option character for the next
@@ -216,7 +216,7 @@ returns @code{-1}.  There may still be more non-option arguments; you
 must compare the external variable @code{optind} against the @var{argv}
 parameter to check this.
 
-If the options has an argument, @code{getopt} returns the argument by
+If the option has an argument, @code{getopt} returns the argument by
 storing it in the varables @var{optarg}.  You don't ordinarily need to
 copy the @code{optarg} string, since it is a pointer into the original
 @var{argv} array, not into a static area that might be overwritten.
@@ -225,7 +225,7 @@ If @code{getopt} finds an option character in @var{argv} that was not
 included in @var{options}, or a missing option argument, it returns
 @samp{?} and sets the external variable @code{optopt} to the actual
 option character.  In addition, if the external variable @code{opterr}
-is nonzero, @code{getopt} prints an error message.
+is nonzero (which is the default), @code{getopt} prints an error message.
 @end deftypefun
 
 @node Example of Getopt
@@ -311,34 +311,35 @@ element containing all zeros.
 The @code{struct option} structure has these fields:
 
 @table @code
-@item name
+@item const char *name
 This field is the name of the option.  It is a string.
 
-@item has_arg
+@item int has_arg
 This field says whether the option takes an argument.  It is an integer,
 and there are three legitimate values: @code{no_argument},
 @code{required_argument} and @code{optional_argument}.
 
-@item flag
-@itemx val
+@item int *flag
+@itemx int val
 These fields control how to report or act on the option when it occurs.
 
-If @code{flag} is zero, then the @code{val} is a value which identifies
-this option.  Often these values are chosen to uniquely identify
-particular long options.
+If @code{flag} is a null pointer, then the @code{val} is a value which
+identifies this option.  Often these values are chosen to uniquely
+identify particular long options.
 
-If @code{flag} is nonzero, it should be the address of an @code{int}
-variable which is the flag for this option.  The value in @code{val} is
-the value to store in the flag to indicate that the option was seen.
+If @code{flag} is not a null pointer, it should be the address of an
+@code{int} variable which is the flag for this option.  The value in
+@code{val} is the value to store in the flag to indicate that the option
+was seen.
 @end table
 @end deftp
 
 @comment getopt.h
 @comment GNU
-@deftypefun int getopt_long (int @var{argc}, char **@var{argv}, const char *@var{short}, struct option *@var{long}, int *@var{indexptr})
+@deftypefun int getopt_long (int @var{argc}, char **@var{argv}, const char *@var{shortopts}, struct option *@var{longopts}, int *@var{indexptr})
 Decode options from the vector @var{argv} (whose length is @var{argc}).
-The argument @var{short} describes the short options to accept, just as
-it does in @code{getopt}.  The argument @var{long} describes the long
+The argument @var{shortopts} describes the short options to accept, just as
+it does in @code{getopt}.  The argument @var{longopts} describes the long
 options to accept (see above).
 
 When @code{getopt_long} encounters a short option, it does the same
@@ -349,31 +350,31 @@ When @code{getopt_long} encounters a long option, it takes actions based
 on the @code{flag} and @code{val} fields of the definition of that
 option.
 
-If @code{flag} is zero, then @code{getopt_long} returns the contents of
-@code{val} to indicate which option it found.  You should arrange
-distinct values in the @code{val} field for options with different
-meanings, so you can decode these values after @code{getopt_long}
-returns.  If the long option is equivalent to a short option, you can
-use the short option's character code in @code{val}.
+If @code{flag} is a null pointer, then @code{getopt_long} returns the
+contents of @code{val} to indicate which option it found.  You should
+arrange distinct values in the @code{val} field for options with
+different meanings, so you can decode these values after
+@code{getopt_long} returns.  If the long option is equivalent to a short
+option, you can use the short option's character code in @code{val}.
 
-If @code{flag} is nonzero, that means this option should just set a flag
-in the program.  The flag is a variable of type @code{int} that you
-define.  Put the address of the flag in the @code{flag} field.  Put in
-the @code{val} field the value you would like this option to store in
-the flag.  In this case, @code{getopt_long} returns @code{0}.
+If @code{flag} is not a null pointer, that means this option should just
+set a flag in the program.  The flag is a variable of type @code{int}
+that you define.  Put the address of the flag in the @code{flag} field.
+Put in the @code{val} field the value you would like this option to
+store in the flag.  In this case, @code{getopt_long} returns @code{0}.
 
 For any long option, @code{getopt_long} tells you the index in the array
-@var{long} of the options definition, by storing it into
+@var{longopts} of the options definition, by storing it into
 @code{*@var{indexptr}}.  You can get the name of the option with
-@code{@var{long}[*@var{indexptr}].name}.  So you can distinguish among
+@code{@var{longopts}[*@var{indexptr}].name}.  So you can distinguish among
 long options either by the values in their @code{val} fields or by their
 indices.  You can also distinguish in this way among long options that
 set flags.
 
 When a long option has an argument, @code{getopt_long} puts the argument
 value in the variable @code{optarg} before returning.  When the option
-has no argument, the value in @code{optarg} is @code{0}.  This is how
-you can tell whether an optional argument was supplied.
+has no argument, the value in @code{optarg} is a null pointer.  This is
+how you can tell whether an optional argument was supplied.
 
 When @code{getopt_long} has no more options to handle, it returns
 @code{-1}, and leaves in the variable @code{optind} the index in
@@ -394,8 +395,8 @@ When @code{getopt_long} has no more options to handle, it returns
 When a program is executed, it receives information about the context in
 which it was invoked in two ways.  The first mechanism uses the
 @var{argv} and @var{argc} arguments to its @code{main} function, and is
-discussed in @ref{Program Arguments}.  The second mechanism is
-uses @dfn{environment variables} and is discussed in this section.
+discussed in @ref{Program Arguments}.  The second mechanism uses
+@dfn{environment variables} and is discussed in this section.
 
 The @var{argv} mechanism is typically used to pass command-line
 arguments specific to the particular program being invoked.  The
@@ -407,6 +408,7 @@ The environment variables discussed in this section are the same
 environment variables that you set using assignments and the
 @code{export} command in the shell.  Programs executed from the shell
 inherit all of the environment variables from the shell.
+@c !!! xref to right part of bash manual when it exists
 
 @cindex environment
 Standard environment variables are used for information about the user's
@@ -447,9 +449,10 @@ The value of an environment variable can be accessed with the
 This function returns a string that is the value of the environment
 variable @var{name}.  You must not modify this string.  In some systems
 not using the GNU library, it might be overwritten by subsequent calls
-to @code{getenv} (but not by any other library function).  If the
-environment variable @var{name} is not defined, the value is a null
-pointer.
+to @code{getenv} (but not by any other library function).
+@c !!! never overwritten on any unix system
+If the environment variable @var{name} is not defined, the value is a
+null pointer.
 @end deftypefun
 
 
@@ -466,6 +469,8 @@ The GNU library provides this function for compatibility with SVID; it
 may not be available in other systems.
 @end deftypefun
 
+@c !!! BSD function setenv
+
 You can deal directly with the underlying representation of environment
 objects to add more variables to the environment (for example, to
 communicate with another program you are about to execute; see
@@ -480,8 +485,7 @@ strings appear in the environment is not significant, but the same
 @var{name} must not appear more than once.  The last element of the
 array is a null pointer.
 
-This variable is not declared in any header file, but if you declare it
-in your own program as @code{extern}, the right thing will happen.
+This variable is declared in the header file @file{unistd.h}.
 
 If you just want to get the value of an environment variable, use
 @code{getenv}.
@@ -496,10 +500,12 @@ that they are always present in the environment; but if these variables
 @emph{are} present, they have these meanings, and that you shouldn't try
 to use these environment variable names for some other purpose.
 
+@comment Extra blank lines make it look better.
 @table @code
 @item HOME
 @cindex HOME environment variable
 @cindex home directory
+
 This is a string representing the user's @dfn{home directory}, or
 initial default working directory.
 
@@ -511,8 +517,10 @@ look up the user's name in the user database (@pxref{User Database}).
 For most purposes, it is better to use @code{HOME}, precisely because
 this lets the user specify the value.
 
+@c !!! also USER
 @item LOGNAME
 @cindex LOGNAME environment variable
+
 This is the name that the user used to log in.  Since the value in the
 environment can be tweaked arbitrarily, this is not a reliable way to
 identify the user who is running a process; a function like
@@ -523,8 +531,9 @@ this lets the user specify the value.
 
 @item PATH
 @cindex PATH environment variable
+
 A @dfn{path} is a sequence of directory names which is used for
-searching for a file.  The variable @var{PATH} holds a path used
+searching for a file.  The variable @code{PATH} holds a path used
 for searching for programs to be run.
 
 The @code{execlp} and @code{execvp} functions (@pxref{Executing a File})
@@ -538,16 +547,18 @@ current directory (@pxref{Working Directory}).
 A typical value for this environment variable might be a string like:
 
 @example
-.:/bin:/etc:/usr/bin:/usr/new/X11:/usr/new:/usr/local:/usr/local/bin
+:/bin:/etc:/usr/bin:/usr/new/X11:/usr/new:/usr/local:/usr/local/bin
 @end example
 
 This means that if the user tries to execute a program named @code{foo},
-the system will look for files named @file{./foo}, @file{/bin/foo},
+the system will look for files named @file{foo}, @file{/bin/foo},
 @file{/etc/foo}, and so on.  The first of these files that exists is
 the one that is executed.
 
+@c !!! also TERMCAP
 @item TERM
 @cindex TERM environment variable
+
 This specifies the kind of terminal that is receiving program output.
 Some programs can make use of this information to take advantage of
 special escape sequences or terminal modes supported by particular kinds
@@ -557,11 +568,13 @@ Manual}) use the @code{TERM} environment variable, for example.
 
 @item TZ
 @cindex TZ environment variable
+
 This specifies the time zone.  @xref{TZ Variable}, for information about
 the format of this string and how it is used.
 
 @item LANG
 @cindex LANG environment variable
+
 This specifies the default locale to use for attribute categories where
 neither @code{LC_ALL} nor the specific environment variable for that
 category is set.  @xref{Locales}, for more information about
@@ -571,6 +584,7 @@ locales.
 @c I doubt this really exists
 @item LC_ALL
 @cindex LC_ALL environment variable
+
 This is similar to the @code{LANG} environment variable.  However, its
 value takes precedence over any values provided for the individual
 attribute category environment variables, or for the @code{LANG}
@@ -579,29 +593,37 @@ environment variable.
 
 @item LC_COLLATE
 @cindex LC_COLLATE environment variable
+
 This specifies what locale to use for string sorting.
 
 @item LC_CTYPE
 @cindex LC_CTYPE environment variable
+
 This specifies what locale to use for character sets and character
 classification.
 
 @item LC_MONETARY
 @cindex LC_MONETARY environment variable
+
 This specifies what locale to use for formatting monetary values.
 
 @item LC_NUMERIC
 @cindex LC_NUMERIC environment variable
+
 This specifies what locale to use for formatting numbers.
 
 @item LC_TIME
 @cindex LC_TIME environment variable
+
 This specifies what locale to use for formatting date/time values.
 
 @item _POSIX_OPTION_ORDER
 @cindex _POSIX_OPTION_ORDER environment variable.
+
 If this environment variable is defined, it suppresses the usual
 reordering of command line arguments by @code{getopt}.  @xref{Argument Syntax}.
+
+@c !!! GNU also has COREFILE, CORESERVER, EXECSERVERS
 @end table
 
 @node Program Termination
@@ -665,7 +687,7 @@ All open streams are closed, writing out any buffered output data.  See
 with the @code{tmpfile} function are removed; see @ref{Temporary Files}.
 
 @item 
-@code{_exit} is called.  @xref{Termination Internals}.
+@code{_exit} is called, terminating the program.  @xref{Termination Internals}.
 @end enumerate
 
 @node Exit Status
@@ -750,7 +772,7 @@ using @code{atexit} or @code{on_exit}.
 
 @comment stdlib.h
 @comment ANSI
-@deftypefun int atexit (void (*@var{function}) ())
+@deftypefun int atexit (void (*@var{function}) (void))
 The @code{atexit} function registers the function @var{function} to be
 called at normal program termination.  The @var{function} is called with
 no arguments.
@@ -776,21 +798,7 @@ Here's a trivial program that illustrates the use of @code{exit} and
 @code{atexit}:
 
 @example
-#include <stdio.h>
-#include <stdlib.h>
-
-void
-bye ()
-@{
-  printf ("Goodbye, cruel world....\n");
-@}
-
-void
-main ()
-@{
-  atexit (bye);
-  exit (EXIT_SUCCESS);
-@}
+@include atexit.c.texi
 @end example
 
 @noindent
@@ -806,7 +814,7 @@ for this function is in @file{stdlib.h}.
 
 @comment stdlib.h
 @comment ANSI
-@deftypefun void abort ()
+@deftypefun void abort (void)
 The @code{abort} function causes abnormal program termination.  This
 does not execute cleanup functions registered with @code{atexit} or
 @code{on_exit}.
@@ -817,10 +825,12 @@ intercept this signal; see @ref{Signal Handling}.
 @end deftypefun
 
 @c Put in by rms.  Don't remove.
+@cartouche
 @strong{Future Change Warning:} Proposed Federal censorship regulations
 may prohibit us from giving you information about the possibility of
 calling this function.  We would be required to say that this is not an
 acceptable way of terminating a program.
+@end cartouche
 
 @node Termination Internals
 @subsection Termination Internals