1 /* 2 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley Software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 #pragma ident "%Z%%M% %I% %E% SMI" 16 17 /* 18 * Compatibility lib for BSD's wait3(). It is not 19 * binary compatible, since BSD's WNOHANG and WUNTRACED 20 * carry different #define values. 21 */ 22 #include <errno.h> 23 #include <sys/types.h> 24 #include <sys/time.h> 25 #include <sys/times.h> 26 #include <wait.h> 27 #include <sys/siginfo.h> 28 #include <sys/procset.h> 29 #include <sys/param.h> 30 #include <sys/resource.h> 31 32 /* 33 * Since sysV does not support rusage as in BSD, an approximate approach 34 * is: 35 * ... 36 * call times 37 * call waitid 38 * if ( a child is found ) 39 * call times again 40 * rusage ~= diff in the 2 times call 41 * ... 42 * 43 */ 44 45 /* 46 * XXX: There is now a wait3 function in libc which should be used instead 47 * of this local version of wait3. With the addition of a wait3 prototype 48 * in <sys/wait.h> as per the X/Open XPG4v2 specification, compilation of 49 * the csh utility will result in warnings, hence the renaming of the local 50 * version. Using the libc wait3 rather than the local version results in 51 * a failure with csh, however, this version should eventually be dropped 52 * in favor of the libc wait3 with appropriate updates made to sh.proc.c 53 * to account for the difference in implementation of the local versus 54 * the libc versions. This should probably be done as part of an overall 55 * effort to rid csh of local versions of functions now in libc. 56 */ 57 58 csh_wait3(status, options, rp) 59 int *status; 60 int options; 61 struct rusage *rp; 62 63 { 64 struct tms before_tms; 65 struct tms after_tms; 66 siginfo_t info; 67 int error; 68 69 if (rp) 70 memset((void *)rp, 0, sizeof(struct rusage)); 71 memset((void *)&info, 0, sizeof(siginfo_t)); 72 if ( times(&before_tms) == -1 ) 73 return (-1); /* errno is set by times() */ 74 75 /* 76 * BSD's wait3() only supports WNOHANG & WUNTRACED 77 */ 78 options |= (WNOHANG|WUNTRACED|WEXITED|WSTOPPED|WTRAPPED|WCONTINUED); 79 error = waitid(P_ALL, 0, &info, options); 80 if ( error == 0 ) { 81 clock_t diffu; /* difference in usertime (ticks) */ 82 clock_t diffs; /* difference in systemtime (ticks) */ 83 84 if ( (options & WNOHANG) && (info.si_pid == 0) ) 85 return (0); /* no child found */ 86 87 if (rp) { 88 if ( times(&after_tms) == -1 ) 89 return (-1); /* errno set by times() */ 90 /* 91 * The system/user time is an approximation only !!! 92 */ 93 diffu = after_tms.tms_cutime - before_tms.tms_cutime; 94 diffs = after_tms.tms_cstime - before_tms.tms_cstime; 95 rp->ru_utime.tv_sec = diffu/HZ; 96 rp->ru_utime.tv_usec = (diffu % HZ) / HZ * 1000000; 97 rp->ru_stime.tv_sec = diffs/HZ; 98 rp->ru_stime.tv_usec = (diffs % HZ) / HZ * 1000000; 99 } 100 *status = wstat(info.si_code, info.si_status); 101 return (info.si_pid); 102 103 } else { 104 return (-1); /* error number is set by waitid() */ 105 } 106 } 107 108 /* 109 * Convert the status code to old style wait status 110 */ 111 wstat(code, status) 112 int code; 113 int status; 114 { 115 register stat = (status & 0377); 116 117 switch (code) { 118 case CLD_EXITED: 119 stat <<= 8; 120 break; 121 case CLD_DUMPED: 122 stat |= WCOREFLG; 123 break; 124 case CLD_KILLED: 125 break; 126 case CLD_TRAPPED: 127 case CLD_STOPPED: 128 stat <<= 8; 129 stat |= WSTOPFLG; 130 break; 131 case CLD_CONTINUED: 132 stat = WCONTFLG; 133 break; 134 } 135 return (stat); 136 } 137