]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - manual/process.texi
nss: Turn __nss_database_lookup into a compatibility symbol
[thirdparty/glibc.git] / manual / process.texi
index b1f5ef469a9ee1af1ea8d502c39d0d7bbf040c99..5728bde2cbb20aed6608ad134b32b426c95ffc47 100644 (file)
@@ -1,4 +1,5 @@
-@node Processes
+@node Processes, Inter-Process Communication, Program Basics, Top
+@c %MENU% How to create processes and run other programs
 @chapter Processes
 
 @cindex process
@@ -50,28 +51,63 @@ function.  This function does all the work of running a subprogram, but
 it doesn't give you much control over the details: you have to wait
 until the subprogram terminates before you can do anything else.
 
-@comment stdlib.h
-@comment ISO
 @deftypefun int system (const char *@var{command})
+@standards{ISO, stdlib.h}
 @pindex sh
-This function executes @var{command} as a shell command.  In the GNU C
-library, it always uses the default shell @code{sh} to run the command.
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c system @ascuplugin @ascuheap @asulock @aculock @acsmem
+@c  do_system @ascuplugin @ascuheap @asulock @aculock @acsmem
+@c   sigemptyset dup ok
+@c   libc_lock_lock @asulock @aculock
+@c   ADD_REF ok
+@c   sigaction dup ok
+@c   SUB_REF ok
+@c   libc_lock_unlock @aculock
+@c   sigaddset dup ok
+@c   sigprocmask dup ok
+@c   CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem
+@c    libc_cleanup_region_start @ascuplugin @ascuheap @acsmem
+@c     pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem
+@c      CANCELLATION_P @ascuplugin @ascuheap @acsmem
+@c       CANCEL_ENABLED_AND_CANCELED ok
+@c       do_cancel @ascuplugin @ascuheap @acsmem
+@c    cancel_handler ok
+@c     kill syscall ok
+@c     waitpid dup ok
+@c     libc_lock_lock ok
+@c     sigaction dup ok
+@c     libc_lock_unlock ok
+@c   FORK ok
+@c    clone syscall ok
+@c   waitpid dup ok
+@c   CLEANUP_RESET ok
+@c    libc_cleanup_region_end ok
+@c     pthread_cleanup_pop_restore ok
+@c  SINGLE_THREAD_P ok
+@c  LIBC_CANCEL_ASYNC @ascuplugin @ascuheap @acsmem
+@c   libc_enable_asynccancel @ascuplugin @ascuheap @acsmem
+@c    CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
+@c    do_cancel dup @ascuplugin @ascuheap @acsmem
+@c  LIBC_CANCEL_RESET ok
+@c   libc_disable_asynccancel ok
+@c    lll_futex_wait dup ok
+This function executes @var{command} as a shell command.  In @theglibc{},
+it always uses the default shell @code{sh} to run the command.
 In particular, it searches the directories in @code{PATH} to find
 programs to execute.  The return value is @code{-1} if it wasn't
 possible to create the shell process, and otherwise is the status of the
 shell process.  @xref{Process Completion}, for details on how this
 status code can be interpreted.
 
-If the @var{command} argument is a null pointer a non-zero return value
-indicates that a command processor is available and this function can be
-used at all.
+If the @var{command} argument is a null pointer, a return value of zero
+indicates that no command processor is available.
 
-This function is a cancelation point in multi-threaded programs.  This
+This function is a cancellation point in multi-threaded programs.  This
 is a problem if the thread allocates some resources (like memory, file
 descriptors, semaphores or whatever) at the time @code{system} is
 called.  If the thread gets canceled these resources stay allocated
 until the program ends.  To avoid this calls to @code{system} should be
-protected using cancelation handlers.
+protected using cancellation handlers.
 @c ref pthread_cleanup_push / pthread_cleanup_pop
 
 @pindex stdlib.h
@@ -96,22 +132,19 @@ output channels of the command being executed.
 This section gives an overview of processes and of the steps involved in
 creating a process and making it run another program.
 
-@cindex process ID
-@cindex process lifetime
-Each process is named by a @dfn{process ID} number.  A unique process ID
-is allocated to each process when it is created.  The @dfn{lifetime} of
-a process ends when its termination is reported to its parent process;
-at that time, all of the process resources, including its process ID,
-are freed.
-
 @cindex creating a process
 @cindex forking a process
 @cindex child process
 @cindex parent process
-Processes are created with the @code{fork} system call (so the operation
-of creating a new process is sometimes called @dfn{forking} a process).
-The @dfn{child process} created by @code{fork} is a copy of the original
-@dfn{parent process}, except that it has its own process ID.
+@cindex subprocess
+A new processes is created when one of the functions
+@code{posix_spawn}, @code{fork}, or @code{vfork} is called.  (The
+@code{system} and @code{popen} also create new processes internally.)
+Due to the name of the @code{fork} function, the act of creating a new
+process is sometimes called @dfn{forking} a process.  Each new process
+(the @dfn{child process} or @dfn{subprocess}) is allocated a process
+ID, distinct from the process ID of the parent process.  @xref{Process
+Identification}.
 
 After forking a child process, both the parent and child processes
 continue to execute normally.  If you want your program to wait for a
@@ -138,35 +171,74 @@ too, instead of returning to the previous process image.
 @node Process Identification
 @section Process Identification
 
-The @code{pid_t} data type represents process IDs.  You can get the
-process ID of a process by calling @code{getpid}.  The function
-@code{getppid} returns the process ID of the parent of the current
-process (this is also known as the @dfn{parent process ID}).  Your
-program should include the header files @file{unistd.h} and
+@cindex process ID
+Each process is named by a @dfn{process ID} number, a value of type
+@code{pid_t}.  A process ID is allocated to each process when it is
+created.  Process IDs are reused over time.  The lifetime of a process
+ends when the parent process of the corresponding process waits on the
+process ID after the process has terminated.  @xref{Process
+Completion}.  (The parent process can arrange for such waiting to
+happen implicitly.)  A process ID uniquely identifies a process only
+during the lifetime of the process.  As a rule of thumb, this means
+that the process must still be running.
+
+Process IDs can also denote process groups and sessions.
+@xref{Job Control}.
+
+@cindex thread ID
+@cindex task ID
+@cindex thread group
+On Linux, threads created by @code{pthread_create} also receive a
+@dfn{thread ID}.  The thread ID of the initial (main) thread is the
+same as the process ID of the entire process.  Thread IDs for
+subsequently created threads are distinct.  They are allocated from
+the same numbering space as process IDs.  Process IDs and thread IDs
+are sometimes also referred to collectively as @dfn{task IDs}.  In
+contrast to processes, threads are never waited for explicitly, so a
+thread ID becomes eligible for reuse as soon as a thread exits or is
+canceled.  This is true even for joinable threads, not just detached
+threads.  Threads are assigned to a @dfn{thread group}.  In
+@theglibc{} implementation running on Linux, the process ID is the
+thread group ID of all threads in the process.
+
+You can get the process ID of a process by calling @code{getpid}.  The
+function @code{getppid} returns the process ID of the parent of the
+current process (this is also known as the @dfn{parent process ID}).
+Your program should include the header files @file{unistd.h} and
 @file{sys/types.h} to use these functions.
 @pindex sys/types.h
 @pindex unistd.h
 
-@comment sys/types.h
-@comment POSIX.1
 @deftp {Data Type} pid_t
+@standards{POSIX.1, sys/types.h}
 The @code{pid_t} data type is a signed integer type which is capable
-of representing a process ID.  In the GNU library, this is an @code{int}.
+of representing a process ID.  In @theglibc{}, this is an @code{int}.
 @end deftp
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun pid_t getpid (void)
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getpid} function returns the process ID of the current process.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun pid_t getppid (void)
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getppid} function returns the process ID of the parent of the
 current process.
 @end deftypefun
 
+@deftypefun pid_t gettid (void)
+@standards{Linux, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+The @code{gettid} function returns the thread ID of the current
+thread.  The returned value is obtained from the Linux kernel and is
+not subject to caching.  See the discussion of thread IDs above,
+especially regarding reuse of the IDs of threads which have exited.
+
+This function is specific to Linux.
+@end deftypefun
+
 @node Creating a Process
 @section Creating a Process
 
@@ -174,9 +246,21 @@ The @code{fork} function is the primitive for creating a process.
 It is declared in the header file @file{unistd.h}.
 @pindex unistd.h
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun pid_t fork (void)
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
+@c The nptl/.../linux implementation safely collects fork_handlers into
+@c an alloca()ed linked list and increments ref counters; it uses atomic
+@c ops and retries, avoiding locking altogether.  It then takes the
+@c IO_list lock, resets the thread-local pid, and runs fork.  The parent
+@c restores the thread-local pid, releases the lock, and runs parent
+@c handlers, decrementing the ref count and signaling futex wait if
+@c requested by unregister_atfork.  The child bumps the fork generation,
+@c sets the thread-local pid, resets cpu clocks, initializes the robust
+@c mutex list, the stream locks, the IO_list lock, the dynamic loader
+@c lock, runs the child handlers, reseting ref counters to 1, and
+@c initializes the fork lock.  These are all safe, unless atfork
+@c handlers themselves are unsafe.
 The @code{fork} function creates a new process.
 
 If the operation is successful, there are then both parent and child
@@ -239,18 +323,20 @@ signals and signal actions from the parent process.)
 @end itemize
 
 
-@comment unistd.h
-@comment BSD
 @deftypefun pid_t vfork (void)
-The @code{vfork} function is similar to @code{fork} but on systems it
-is more efficient; however, there are restrictions you must follow to
+@standards{BSD, unistd.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
+@c The vfork implementation proper is a safe syscall, but it may fall
+@c back to fork if the vfork syscall is not available.
+The @code{vfork} function is similar to @code{fork} but on some systems
+it is more efficient; however, there are restrictions you must follow to
 use it safely.
 
-While @code{fork} makes a complete copy of the calling process's
-address space and allows both the parent and child to execute
-independently, @code{vfork} does not make this copy.  Instead, the
-child process created with @code{vfork} shares its parent's address
-space until it calls exits or one of the @code{exec} functions.  In the
+While @code{fork} makes a complete copy of the calling process's address
+space and allows both the parent and child to execute independently,
+@code{vfork} does not make this copy.  Instead, the child process
+created with @code{vfork} shares its parent's address space until it
+calls @code{_exit} or one of the @code{exec} functions.  In the
 meantime, the parent process suspends execution.
 
 You must be very careful not to allow the child process created with
@@ -260,8 +346,8 @@ do a long jump out of) the function that called @code{vfork}!  This
 would leave the parent process's control information very confused.  If
 in doubt, use @code{fork} instead.
 
-Some operating systems don't really implement @code{vfork}.  The GNU C
-library permits you to use @code{vfork} on all systems, but actually
+Some operating systems don't really implement @code{vfork}.  @Theglibc{}
+permits you to use @code{vfork} on all systems, but actually
 executes @code{fork} if @code{vfork} isn't available.  If you follow
 the proper precautions for using @code{vfork}, your program will still
 work even if the system uses @code{fork} instead.
@@ -276,14 +362,17 @@ This section describes the @code{exec} family of functions, for executing
 a file as a process image.  You can use these functions to make a child
 process execute a new program after it has been forked.
 
+To see the effects of @code{exec} from the point of view of the called
+program, see @ref{Program Basics}.
+
 @pindex unistd.h
 The functions in this family differ in how you specify the arguments,
 but otherwise they all do the same thing.  They are declared in the
 header file @file{unistd.h}.
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{execv} function executes the file named by @var{filename} as a
 new process image.
 
@@ -299,26 +388,26 @@ The environment for the new process image is taken from the
 @ref{Environment Variables}, for information about environments.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This is similar to @code{execv}, but the @var{argv} strings are
 specified individually instead of as an array.  A null pointer must be
 passed as the last such argument.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This is similar to @code{execv}, but permits you to specify the environment
 for the new program explicitly as the @var{env} argument.  This should
 be an array of strings in the same format as for the @code{environ}
 variable; see @ref{Environment Access}.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
-@deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, char *const @var{env}@t{[]}, @dots{})
+@deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, @dots{}, char *const @var{env}@t{[]})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This is similar to @code{execl}, but permits you to specify the
 environment for the new program explicitly.  The environment argument is
 passed following the null pointer that marks the last @var{argv}
@@ -326,9 +415,9 @@ argument, and should be an array of strings in the same format as for
 the @code{environ} variable.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 The @code{execvp} function is similar to @code{execv}, except that it
 searches the directories listed in the @code{PATH} environment variable
 (@pxref{Standard Environment}) to find the full file name of a
@@ -339,16 +428,16 @@ it looks for them in the places that the user has chosen.  Shells use it
 to run the commands that users type.
 @end deftypefun
 
-@comment unistd.h
-@comment POSIX.1
 @deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{})
+@standards{POSIX.1, unistd.h}
+@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This function is like @code{execl}, except that it performs the same
 file name searching as the @code{execvp} function.
 @end deftypefun
 
 The size of the argument list and environment list taken together must
-not be greater than @code{ARG_MAX} bytes.  @xref{General Limits}.  In
-the GNU system, the size (which compares against @code{ARG_MAX})
+not be greater than @code{ARG_MAX} bytes.  @xref{General Limits}.  On
+@gnuhurdsystems{}, the size (which compares against @code{ARG_MAX})
 includes, for each string, the number of characters in the string, plus
 the size of a @code{char *}, plus one, rounded up to a multiple of the
 size of a @code{char *}.  Other systems may have somewhat different
@@ -363,7 +452,7 @@ usual file name errors (@pxref{File Name Errors}), the following
 @table @code
 @item E2BIG
 The combined size of the new program's argument list and environment
-list is larger than @code{ARG_MAX} bytes.  The GNU system has no
+list is larger than @code{ARG_MAX} bytes.  @gnuhurdsystems{} have no
 specific limit on the argument list size, so this error code cannot
 result, but you may get @code{ENOMEM} instead if the arguments are too
 big for available memory.
@@ -403,7 +492,7 @@ Pending alarms.  @xref{Setting an Alarm}.
 
 @item
 Current working directory and root directory.  @xref{Working
-Directory}.  In the GNU system, the root directory is not copied when
+Directory}.  On @gnuhurdsystems{}, the root directory is not copied when
 executing a setuid program; instead the system default root directory
 is used for the new program.
 
@@ -433,7 +522,7 @@ information about signals, see @ref{Signal Handling}.
 File descriptors open in the existing process image remain open in the
 new process image, unless they have the @code{FD_CLOEXEC}
 (close-on-exec) flag set.  The files that remain open inherit all
-attributes of the open file description from the existing process image,
+attributes of the open file descriptors from the existing process image,
 including file locks.  File descriptors are discussed in @ref{Low-Level I/O}.
 
 Streams, by contrast, cannot survive through @code{exec} functions,
@@ -456,9 +545,9 @@ process to terminate or stop, and determine its status.  These functions
 are declared in the header file @file{sys/wait.h}.
 @pindex sys/wait.h
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status-ptr}, int @var{options})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{waitpid} function is used to request status information from a
 child process whose process ID is @var{pid}.  Normally, the calling
 process is suspended until the child process makes status information
@@ -489,12 +578,12 @@ processes as well as processes that have terminated.
 The status information from the child process is stored in the object
 that @var{status-ptr} points to, unless @var{status-ptr} is a null pointer.
 
-This function is a cancelation point in multi-threaded programs.  This
+This function is a cancellation point in multi-threaded programs.  This
 is a problem if the thread allocates some resources (like memory, file
 descriptors, semaphores or whatever) at the time @code{waitpid} is
 called.  If the thread gets canceled these resources stay allocated
 until the program ends.  To avoid this calls to @code{waitpid} should be
-protected using cancelation handlers.
+protected using cancellation handlers.
 @c ref pthread_cleanup_push / pthread_cleanup_pop
 
 The return value is normally the process ID of the child process whose
@@ -529,7 +618,7 @@ These symbolic constants are defined as values for the @var{pid} argument
 to the @code{waitpid} function.
 
 @comment Extra blank lines make it look better.
-@table @code
+@vtable @code
 @item WAIT_ANY
 
 This constant macro (whose value is @code{-1}) specifies that
@@ -540,13 +629,13 @@ This constant macro (whose value is @code{-1}) specifies that
 This constant (with value @code{0}) specifies that @code{waitpid} should
 return status information about any child process in the same process
 group as the calling process.
-@end table
+@end vtable
 
 These symbolic constants are defined as flags for the @var{options}
 argument to the @code{waitpid} function.  You can bitwise-OR the flags
 together to obtain a value to use as the argument.
 
-@table @code
+@vtable @code
 @item WNOHANG
 
 This flag specifies that @code{waitpid} should return immediately
@@ -557,11 +646,11 @@ instead of waiting, if there is no child process ready to be noticed.
 This flag specifies that @code{waitpid} should report the status of any
 child processes that have been stopped as well as those that have
 terminated.
-@end table
+@end vtable
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefun pid_t wait (int *@var{status-ptr})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This is a simplified version of @code{waitpid}, and is used to wait
 until any one child process terminates.  The call:
 
@@ -576,18 +665,18 @@ is exactly equivalent to:
 waitpid (-1, &status, 0)
 @end smallexample
 
-This function is a cancelation point in multi-threaded programs.  This
+This function is a cancellation point in multi-threaded programs.  This
 is a problem if the thread allocates some resources (like memory, file
 descriptors, semaphores or whatever) at the time @code{wait} is
 called.  If the thread gets canceled these resources stay allocated
 until the program ends.  To avoid this calls to @code{wait} should be
-protected using cancelation handlers.
+protected using cancellation handlers.
 @c ref pthread_cleanup_push / pthread_cleanup_pop
 @end deftypefun
 
-@comment sys/wait.h
-@comment BSD
 @deftypefun pid_t wait4 (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
+@standards{BSD, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If @var{usage} is a null pointer, @code{wait4} is equivalent to
 @code{waitpid (@var{pid}, @var{status-ptr}, @var{options})}.
 
@@ -608,8 +697,8 @@ indicates that at least one child process has terminated.
 void
 sigchld_handler (int signum)
 @{
-  int pid;
-  int status;
+  int pid, status, serrno;
+  serrno = errno;
   while (1)
     @{
       pid = waitpid (WAIT_ANY, &status, WNOHANG);
@@ -622,6 +711,7 @@ sigchld_handler (int signum)
         break;
       notice_termination (pid, status);
     @}
+  errno = serrno;
 @}
 @end group
 @end smallexample
@@ -636,105 +726,69 @@ encoded in the returned status value using the following macros.
 These macros are defined in the header file @file{sys/wait.h}.
 @pindex sys/wait.h
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WIFEXITED (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 normally with @code{exit} or @code{_exit}.
 @end deftypefn
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WEXITSTATUS (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFEXITED} is true of @var{status}, this macro returns the
 low-order 8 bits of the exit status value from the child process.
 @xref{Exit Status}.
 @end deftypefn
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WIFSIGNALED (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 because it received a signal that was not handled.
 @xref{Signal Handling}.
 @end deftypefn
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WTERMSIG (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFSIGNALED} is true of @var{status}, this macro returns the
 signal number of the signal that terminated the child process.
 @end deftypefn
 
-@comment sys/wait.h
-@comment BSD
 @deftypefn Macro int WCOREDUMP (int @var{status})
+@standards{BSD, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 and produced a core dump.
 @end deftypefn
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WIFSTOPPED (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process is stopped.
 @end deftypefn
 
-@comment sys/wait.h
-@comment POSIX.1
 @deftypefn Macro int WSTOPSIG (int @var{status})
+@standards{POSIX.1, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFSTOPPED} is true of @var{status}, this macro returns the
 signal number of the signal that caused the child process to stop.
 @end deftypefn
 
 
 @node BSD Wait Functions
-@section BSD Process Wait Functions
+@section BSD Process Wait Function
 
-The GNU library also provides these related facilities for compatibility
-with BSD Unix.  BSD uses the @code{union wait} data type to represent
-status values rather than an @code{int}.  The two representations are
-actually interchangeable; they describe the same bit patterns.  The GNU
-C Library defines macros such as @code{WEXITSTATUS} so that they will
-work on either kind of object, and the @code{wait} function is defined
-to accept either type of pointer as its @var{status-ptr} argument.
-
-These functions are declared in @file{sys/wait.h}.
+@Theglibc{} also provides the @code{wait3} function for compatibility
+with BSD.  This function is declared in @file{sys/wait.h}.  It is the
+predecessor to @code{wait4}, which is more flexible.  @code{wait3} is
+now obsolete.
 @pindex sys/wait.h
 
-@comment sys/wait.h
-@comment BSD
-@deftp {Data Type} {union wait}
-This data type represents program termination status values.  It has
-the following members:
-
-@table @code
-@item int w_termsig
-The value of this member is the same as that of the
-@code{WTERMSIG} macro.
-
-@item int w_coredump
-The value of this member is the same as that of the
-@code{WCOREDUMP} macro.
-
-@item int w_retcode
-The value of this member is the same as that of the
-@code{WEXITSTATUS} macro.
-
-@item int w_stopsig
-The value of this member is the same as that of the
-@code{WSTOPSIG} macro.
-@end table
-
-Instead of accessing these members directly, you should use the
-equivalent macros.
-@end deftp
-
-The @code{wait3} function is the predecessor to @code{wait4}, which is
-more flexible.  @code{wait3} is now obsolete.
-
-@comment sys/wait.h
-@comment BSD
-@deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
+@deftypefun pid_t wait3 (int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
+@standards{BSD, sys/wait.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If @var{usage} is a null pointer, @code{wait3} is equivalent to
 @code{waitpid (-1, @var{status-ptr}, @var{options})}.