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