1: # include <useful.h> 2: # include <errno.h> 3: # include <sccs.h> 4: 5: SCCSID(@(#)fullwait.c 8.3 2/8/85) 6: 7: /* 8: ** FULLWAIT -- performs a wait(II) primitive for a given child. 9: ** 10: ** The wait primitive is executed as many times as needed to get 11: ** termination status for a given child. The case of an interrupt 12: ** during the wait is handled. No other children may die during 13: ** the wait. Also, the child must die "normally", that is, as the 14: ** result of an exit() system call, or from an interrupt. 15: ** 16: ** Parameters: 17: ** "child" -- the pid of the child process to wait for, 18: ** returned from the fork() system call. 19: ** "name" -- a character string representing the name of 20: ** the calling routine; printed on syserr's. 21: ** Returns: 22: ** The exit parameter of the child process. 23: */ 24: 25: fullwait(child, name) 26: int child; 27: char *name; 28: { 29: auto int st; 30: register int i; 31: extern int errno; 32: register char *n; 33: register char *coredump; 34: 35: n = name; 36: 37: /* wait for a child to die */ 38: while ((i = wait(&st)) != child) 39: { 40: /* it is not the child we want; chew on it a little more */ 41: if (i != -1) 42: syserr("%s: unexpected child: pid %d st 0%o", n, i, st); 43: 44: /* check for interrupted system call */ 45: if (errno != EINTR) 46: { 47: /* wait with no child */ 48: syserr("%s: no child", n); 49: } 50: errno = 0; 51: 52: /* dropped out from signal: reexecute the wait */ 53: } 54: 55: /* check termination status */ 56: i = st & I1MASK; 57: if (i > 2) 58: { 59: /* child collapsed */ 60: if (i & 0200) 61: { 62: coredump = " -- core dumped"; 63: i &= 0177; 64: } 65: else 66: { 67: coredump = ""; 68: } 69: syserr("bad status %s: stat %d%s", n, i, coredump); 70: } 71: 72: /* return exit status */ 73: return (st >> 8); 74: }