Back to index

glibc  2.9
waitpid.c
Go to the documentation of this file.
00001 /* Copyright (C) 1993,94,95,96,97,2002,2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Brendan Kehoe (brendan@zen.org).
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <sys/wait.h>
00022 #include <sys/types.h>
00023 #include <stddef.h>
00024 #include "siginfo.h"
00025 
00026 typedef enum __idtype
00027   {
00028     /* Look for processes based upon a given PID.  */
00029     P_PID,
00030 
00031     /* Look for processes based upon a given process-group ID.  */
00032     P_PGID = 2,
00033 
00034     /* Look for any process.  */
00035     P_ALL = 7,
00036   } __idtype_t;
00037 
00038 extern __pid_t __getpgid (__pid_t pid);
00039 extern int __waitid (__idtype_t idtype, __pid_t id,
00040                    __siginfo_t *infop, int options);
00041 
00042 /* Wait for a child matching PID to die.
00043    If PID is greater than 0, match any process whose process ID is PID.
00044    If PID is (pid_t) -1, match any process.
00045    If PID is (pid_t) 0, match any process with the
00046    same process group as the current process.
00047    If PID is less than -1, match any process whose
00048    process group is the absolute value of PID.
00049    If the WNOHANG bit is set in OPTIONS, and that child
00050    is not already dead, return (pid_t) 0.  If successful,
00051    return PID and store the dead child's status in STAT_LOC.
00052    Return (pid_t) -1 for errors.  If the WUNTRACED bit is set in OPTIONS,
00053    return status for stopped children; otherwise don't.  */
00054 
00055 __pid_t
00056 __libc_waitpid (__pid_t pid, int *stat_loc, int options)
00057 {
00058   __idtype_t idtype;
00059   __pid_t tmp_pid = pid;
00060   __siginfo_t infop;
00061 
00062   if (pid <= WAIT_MYPGRP)
00063     {
00064       if (pid == WAIT_ANY)
00065        {
00066          /* Request the status for any child.  */
00067          idtype = P_ALL;
00068        }
00069       else if (pid == WAIT_MYPGRP)
00070        {
00071          /* Request the status for any child process that has
00072             a pgid that's equal to that of our parent.  */
00073          tmp_pid = __getpgid (0);
00074          idtype = P_PGID;
00075        }
00076       else /* PID < -1 */
00077        {
00078          /* Request the status for any child whose pgid is equal
00079             to the absolute value of PID.  */
00080          tmp_pid = pid & ~0; /* XXX not pseudo-insn */
00081          idtype = P_PGID;
00082        }
00083     }
00084   else
00085     {
00086       /* Request the status for the child whose pid is PID.  */
00087       idtype = P_PID;
00088     }
00089 
00090   if (__waitid (idtype, tmp_pid, &infop, options | WEXITED | WTRAPPED) < 0)
00091     return -1;
00092 
00093   switch (infop.__code)
00094     {
00095     case EXITED:
00096       *stat_loc = W_EXITCODE (infop.__status, 0);
00097       break;
00098     case STOPPED:
00099     case TRAPPED:
00100       *stat_loc = W_STOPCODE (infop.__status);
00101       break;
00102     case KILLED:
00103       /* Don't know what to do with continue, since it isn't documented.
00104         Putting it here seemed the right place though. */
00105     case CONTINUED:
00106       *stat_loc = infop.__status;
00107       /* FALLTHROUGH */
00108     case CORED:
00109       *stat_loc |= WCOREFLAG;
00110       break;
00111     }
00112 
00113   /* Return the PID out of the INFOP structure instead of the one we were
00114      called with, to account for cases of being called with -1 to signify
00115      any PID.  */
00116   return infop.__pid;
00117 }
00118 weak_alias (__libc_waitpid, __waitpid)
00119 weak_alias (__libc_waitpid, waitpid)
00120 libc_hidden_weak (__waitpid)