* nss/nss_files/files-parse.c (nss_files_parse_hidden_def): Define to
[glibc.git] / sysdeps / unix / sysv / sysv4 / waitpid.c
blob23f9ceb0291ad6277563408fe6374393c8267e43
1 /* Copyright (C) 1993,94,95,96,97,2002,2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Brendan Kehoe (brendan@zen.org).
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <errno.h>
21 #include <sys/wait.h>
22 #include <sys/types.h>
23 #include <stddef.h>
24 #include "siginfo.h"
26 typedef enum __idtype
28 /* Look for processes based upon a given PID. */
29 P_PID,
31 /* Look for processes based upon a given process-group ID. */
32 P_PGID = 2,
34 /* Look for any process. */
35 P_ALL = 7,
36 } __idtype_t;
38 extern __pid_t __getpgid (__pid_t pid);
39 extern int __waitid (__idtype_t idtype, __pid_t id,
40 __siginfo_t *infop, int options);
42 /* Wait for a child matching PID to die.
43 If PID is greater than 0, match any process whose process ID is PID.
44 If PID is (pid_t) -1, match any process.
45 If PID is (pid_t) 0, match any process with the
46 same process group as the current process.
47 If PID is less than -1, match any process whose
48 process group is the absolute value of PID.
49 If the WNOHANG bit is set in OPTIONS, and that child
50 is not already dead, return (pid_t) 0. If successful,
51 return PID and store the dead child's status in STAT_LOC.
52 Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS,
53 return status for stopped children; otherwise don't. */
55 __pid_t
56 __libc_waitpid (__pid_t pid, int *stat_loc, int options)
58 __idtype_t idtype;
59 __pid_t tmp_pid = pid;
60 __siginfo_t infop;
62 if (pid <= WAIT_MYPGRP)
64 if (pid == WAIT_ANY)
66 /* Request the status for any child. */
67 idtype = P_ALL;
69 else if (pid == WAIT_MYPGRP)
71 /* Request the status for any child process that has
72 a pgid that's equal to that of our parent. */
73 tmp_pid = __getpgid (0);
74 idtype = P_PGID;
76 else /* PID < -1 */
78 /* Request the status for any child whose pgid is equal
79 to the absolute value of PID. */
80 tmp_pid = pid & ~0; /* XXX not pseudo-insn */
81 idtype = P_PGID;
84 else
86 /* Request the status for the child whose pid is PID. */
87 idtype = P_PID;
90 if (__waitid (idtype, tmp_pid, &infop, options | WEXITED | WTRAPPED) < 0)
91 return -1;
93 switch (infop.__code)
95 case EXITED:
96 *stat_loc = W_EXITCODE (infop.__status, 0);
97 break;
98 case STOPPED:
99 case TRAPPED:
100 *stat_loc = W_STOPCODE (infop.__status);
101 break;
102 case KILLED:
103 /* Don't know what to do with continue, since it isn't documented.
104 Putting it here seemed the right place though. */
105 case CONTINUED:
106 *stat_loc = infop.__status;
107 /* FALLTHROUGH */
108 case CORED:
109 *stat_loc |= WCOREFLAG;
110 break;
113 /* Return the PID out of the INFOP structure instead of the one we were
114 called with, to account for cases of being called with -1 to signify
115 any PID. */
116 return infop.__pid;
118 weak_alias (__libc_waitpid, __waitpid)
119 weak_alias (__libc_waitpid, waitpid)
120 libc_hidden_weak (__waitpid)