1*b30d1939SAndy Fiddaman /*********************************************************************** 2*b30d1939SAndy Fiddaman * * 3*b30d1939SAndy Fiddaman * This software is part of the ast package * 4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2011 AT&T Intellectual Property * 5*b30d1939SAndy Fiddaman * and is licensed under the * 6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 * 7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property * 8*b30d1939SAndy Fiddaman * * 9*b30d1939SAndy Fiddaman * A copy of the License is available at * 10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html * 11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12*b30d1939SAndy Fiddaman * * 13*b30d1939SAndy Fiddaman * Information and Software Systems Research * 14*b30d1939SAndy Fiddaman * AT&T Research * 15*b30d1939SAndy Fiddaman * Florham Park NJ * 16*b30d1939SAndy Fiddaman * * 17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> * 18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> * 19*b30d1939SAndy Fiddaman * Phong Vo <kpv@research.att.com> * 20*b30d1939SAndy Fiddaman * * 21*b30d1939SAndy Fiddaman ***********************************************************************/ 22*b30d1939SAndy Fiddaman #pragma prototyped 23*b30d1939SAndy Fiddaman /* 24*b30d1939SAndy Fiddaman * POSIX waitpid() 25*b30d1939SAndy Fiddaman * 26*b30d1939SAndy Fiddaman * pid < -1 WUNTRACED may not be fully supported 27*b30d1939SAndy Fiddaman * process group specifics ignored by non-{waitpid,wait4} 28*b30d1939SAndy Fiddaman */ 29*b30d1939SAndy Fiddaman 30*b30d1939SAndy Fiddaman #include <ast.h> 31*b30d1939SAndy Fiddaman #include <wait.h> 32*b30d1939SAndy Fiddaman 33*b30d1939SAndy Fiddaman #if _lib_waitpid 34*b30d1939SAndy Fiddaman 35*b30d1939SAndy Fiddaman NoN(waitpid) 36*b30d1939SAndy Fiddaman 37*b30d1939SAndy Fiddaman #else 38*b30d1939SAndy Fiddaman 39*b30d1939SAndy Fiddaman #if _lib_wait4 40*b30d1939SAndy Fiddaman 41*b30d1939SAndy Fiddaman struct rusage; 42*b30d1939SAndy Fiddaman 43*b30d1939SAndy Fiddaman extern int wait4(int, int*, int, struct rusage*); 44*b30d1939SAndy Fiddaman 45*b30d1939SAndy Fiddaman pid_t 46*b30d1939SAndy Fiddaman waitpid(pid_t pid, int* status, int flags) 47*b30d1939SAndy Fiddaman { 48*b30d1939SAndy Fiddaman return(wait4(pid, status, flags, NiL)); 49*b30d1939SAndy Fiddaman } 50*b30d1939SAndy Fiddaman 51*b30d1939SAndy Fiddaman #else 52*b30d1939SAndy Fiddaman 53*b30d1939SAndy Fiddaman #undef SIGCLD 54*b30d1939SAndy Fiddaman 55*b30d1939SAndy Fiddaman #if _lib_wait3 56*b30d1939SAndy Fiddaman 57*b30d1939SAndy Fiddaman extern int wait3(int*, int, struct rusage*); 58*b30d1939SAndy Fiddaman 59*b30d1939SAndy Fiddaman #else 60*b30d1939SAndy Fiddaman 61*b30d1939SAndy Fiddaman #if _lib_wait2 62*b30d1939SAndy Fiddaman 63*b30d1939SAndy Fiddaman #define wait3(s,f,u) wait2(s,f) 64*b30d1939SAndy Fiddaman 65*b30d1939SAndy Fiddaman extern int wait2(int*, int); 66*b30d1939SAndy Fiddaman 67*b30d1939SAndy Fiddaman #else 68*b30d1939SAndy Fiddaman 69*b30d1939SAndy Fiddaman #include <sig.h> 70*b30d1939SAndy Fiddaman 71*b30d1939SAndy Fiddaman #define wait3(s,f,u) wait(s) 72*b30d1939SAndy Fiddaman 73*b30d1939SAndy Fiddaman static int caught; 74*b30d1939SAndy Fiddaman 75*b30d1939SAndy Fiddaman static void 76*b30d1939SAndy Fiddaman catch(sig) 77*b30d1939SAndy Fiddaman int sig; 78*b30d1939SAndy Fiddaman { 79*b30d1939SAndy Fiddaman NoP(sig); 80*b30d1939SAndy Fiddaman caught = 1; 81*b30d1939SAndy Fiddaman } 82*b30d1939SAndy Fiddaman 83*b30d1939SAndy Fiddaman #endif 84*b30d1939SAndy Fiddaman 85*b30d1939SAndy Fiddaman #endif 86*b30d1939SAndy Fiddaman 87*b30d1939SAndy Fiddaman #include <error.h> 88*b30d1939SAndy Fiddaman 89*b30d1939SAndy Fiddaman struct zombie 90*b30d1939SAndy Fiddaman { 91*b30d1939SAndy Fiddaman struct zombie* next; 92*b30d1939SAndy Fiddaman int status; 93*b30d1939SAndy Fiddaman pid_t pid; 94*b30d1939SAndy Fiddaman }; 95*b30d1939SAndy Fiddaman 96*b30d1939SAndy Fiddaman pid_t 97*b30d1939SAndy Fiddaman waitpid(pid_t pid, int* status, int flags) 98*b30d1939SAndy Fiddaman { 99*b30d1939SAndy Fiddaman register struct zombie* zp; 100*b30d1939SAndy Fiddaman register struct zombie* pp; 101*b30d1939SAndy Fiddaman register int p; 102*b30d1939SAndy Fiddaman int s; 103*b30d1939SAndy Fiddaman #if !_lib_wait2 && !_lib_wait3 104*b30d1939SAndy Fiddaman #if !defined(SIGCLD) 105*b30d1939SAndy Fiddaman int n; 106*b30d1939SAndy Fiddaman int oerrno; 107*b30d1939SAndy Fiddaman #endif 108*b30d1939SAndy Fiddaman Sig_handler_t handler; 109*b30d1939SAndy Fiddaman #endif 110*b30d1939SAndy Fiddaman 111*b30d1939SAndy Fiddaman static struct zombie* zombies; 112*b30d1939SAndy Fiddaman 113*b30d1939SAndy Fiddaman pp = 0; 114*b30d1939SAndy Fiddaman zp = zombies; 115*b30d1939SAndy Fiddaman while (zp) 116*b30d1939SAndy Fiddaman { 117*b30d1939SAndy Fiddaman if (zp->pid >= 0 && (zp->pid == pid || pid <= 0)) 118*b30d1939SAndy Fiddaman { 119*b30d1939SAndy Fiddaman if (pp) pp->next = zp->next; 120*b30d1939SAndy Fiddaman else zombies = zp->next; 121*b30d1939SAndy Fiddaman if (status) *status = zp->status; 122*b30d1939SAndy Fiddaman pid = zp->pid; 123*b30d1939SAndy Fiddaman free(zp); 124*b30d1939SAndy Fiddaman return(pid); 125*b30d1939SAndy Fiddaman } 126*b30d1939SAndy Fiddaman } 127*b30d1939SAndy Fiddaman if (pid > 0 && kill(pid, 0) < 0) return(-1); 128*b30d1939SAndy Fiddaman for (;;) 129*b30d1939SAndy Fiddaman { 130*b30d1939SAndy Fiddaman #if !_lib_wait2 && !_lib_wait3 131*b30d1939SAndy Fiddaman #if !defined(SIGCLD) 132*b30d1939SAndy Fiddaman oerrno = errno; 133*b30d1939SAndy Fiddaman #endif 134*b30d1939SAndy Fiddaman if (flags & WNOHANG) 135*b30d1939SAndy Fiddaman { 136*b30d1939SAndy Fiddaman caught = 0; 137*b30d1939SAndy Fiddaman #if defined(SIGCLD) 138*b30d1939SAndy Fiddaman handler = signal(SIGCLD, catch); 139*b30d1939SAndy Fiddaman if (!caught) 140*b30d1939SAndy Fiddaman { 141*b30d1939SAndy Fiddaman signal(SIGCLD, handler); 142*b30d1939SAndy Fiddaman return(0); 143*b30d1939SAndy Fiddaman } 144*b30d1939SAndy Fiddaman #else 145*b30d1939SAndy Fiddaman #if defined(SIGALRM) 146*b30d1939SAndy Fiddaman handler = signal(SIGALRM, catch); 147*b30d1939SAndy Fiddaman n = alarm(1); 148*b30d1939SAndy Fiddaman #endif 149*b30d1939SAndy Fiddaman #endif 150*b30d1939SAndy Fiddaman } 151*b30d1939SAndy Fiddaman #endif 152*b30d1939SAndy Fiddaman p = wait3(&s, flags, NiL); 153*b30d1939SAndy Fiddaman #if !_lib_wait3 154*b30d1939SAndy Fiddaman #if !_lib_wait2 155*b30d1939SAndy Fiddaman #if defined(SIGCLD) 156*b30d1939SAndy Fiddaman if (flags & WNOHANG) signal(SIGCLD, handler); 157*b30d1939SAndy Fiddaman #else 158*b30d1939SAndy Fiddaman #if defined(SIGALRM) 159*b30d1939SAndy Fiddaman if (flags & WNOHANG) 160*b30d1939SAndy Fiddaman { 161*b30d1939SAndy Fiddaman if (n == 0 && !caught || n == 1) alarm(n); 162*b30d1939SAndy Fiddaman else if (n > 1) alarm(n - caught); 163*b30d1939SAndy Fiddaman signal(SIGALRM, handler); 164*b30d1939SAndy Fiddaman } 165*b30d1939SAndy Fiddaman if (p == -1 && errno == EINTR) 166*b30d1939SAndy Fiddaman { 167*b30d1939SAndy Fiddaman errno = oerrno; 168*b30d1939SAndy Fiddaman p = 0; 169*b30d1939SAndy Fiddaman s = 0; 170*b30d1939SAndy Fiddaman } 171*b30d1939SAndy Fiddaman #endif 172*b30d1939SAndy Fiddaman #endif 173*b30d1939SAndy Fiddaman #else 174*b30d1939SAndy Fiddaman if (p == -1 && errno == EINVAL && (flags & ~WNOHANG)) 175*b30d1939SAndy Fiddaman p = wait3(&s, flags & WNOHANG, NiL); 176*b30d1939SAndy Fiddaman #endif 177*b30d1939SAndy Fiddaman #endif 178*b30d1939SAndy Fiddaman if (p <= 0) 179*b30d1939SAndy Fiddaman { 180*b30d1939SAndy Fiddaman if (p == 0 && status) *status = s; 181*b30d1939SAndy Fiddaman return(p); 182*b30d1939SAndy Fiddaman } 183*b30d1939SAndy Fiddaman if (pid <= 0 || p == pid) 184*b30d1939SAndy Fiddaman { 185*b30d1939SAndy Fiddaman if (status) *status = s; 186*b30d1939SAndy Fiddaman return(p); 187*b30d1939SAndy Fiddaman } 188*b30d1939SAndy Fiddaman if (!(zp = newof(0, struct zombie, 1, 0))) return(-1); 189*b30d1939SAndy Fiddaman zp->pid = p; 190*b30d1939SAndy Fiddaman zp->status = s; 191*b30d1939SAndy Fiddaman zp->next = zombies; 192*b30d1939SAndy Fiddaman zombies = zp; 193*b30d1939SAndy Fiddaman } 194*b30d1939SAndy Fiddaman /*NOTREACHED*/ 195*b30d1939SAndy Fiddaman } 196*b30d1939SAndy Fiddaman 197*b30d1939SAndy Fiddaman #endif 198*b30d1939SAndy Fiddaman 199*b30d1939SAndy Fiddaman #endif 200