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