17c478bd9Sstevel@tonic-gate /*
2*70a587ddSchin * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
78e3c57a3Sraf /* All Rights Reserved */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate */
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate /*
168e3c57a3Sraf * Compatibility lib for BSD's wait3(). It is not
178e3c57a3Sraf * binary compatible, since BSD's WNOHANG and WUNTRACED
188e3c57a3Sraf * carry different #define values.
197c478bd9Sstevel@tonic-gate */
207c478bd9Sstevel@tonic-gate #include <errno.h>
217c478bd9Sstevel@tonic-gate #include <sys/types.h>
227c478bd9Sstevel@tonic-gate #include <sys/time.h>
237c478bd9Sstevel@tonic-gate #include <sys/times.h>
247c478bd9Sstevel@tonic-gate #include <wait.h>
257c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
267c478bd9Sstevel@tonic-gate #include <sys/procset.h>
277c478bd9Sstevel@tonic-gate #include <sys/param.h>
287c478bd9Sstevel@tonic-gate #include <sys/resource.h>
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * Since sysV does not support rusage as in BSD, an approximate approach
327c478bd9Sstevel@tonic-gate * is:
338e3c57a3Sraf * ...
348e3c57a3Sraf * call times
358e3c57a3Sraf * call waitid
368e3c57a3Sraf * if ( a child is found )
378e3c57a3Sraf * call times again
388e3c57a3Sraf * rusage ~= diff in the 2 times call
398e3c57a3Sraf * ...
408e3c57a3Sraf *
417c478bd9Sstevel@tonic-gate */
427c478bd9Sstevel@tonic-gate
438e3c57a3Sraf /*
447c478bd9Sstevel@tonic-gate * XXX: There is now a wait3 function in libc which should be used instead
457c478bd9Sstevel@tonic-gate * of this local version of wait3. With the addition of a wait3 prototype
467c478bd9Sstevel@tonic-gate * in <sys/wait.h> as per the X/Open XPG4v2 specification, compilation of
477c478bd9Sstevel@tonic-gate * the csh utility will result in warnings, hence the renaming of the local
487c478bd9Sstevel@tonic-gate * version. Using the libc wait3 rather than the local version results in
497c478bd9Sstevel@tonic-gate * a failure with csh, however, this version should eventually be dropped
507c478bd9Sstevel@tonic-gate * in favor of the libc wait3 with appropriate updates made to sh.proc.c
518e3c57a3Sraf * to account for the difference in implementation of the local versus
527c478bd9Sstevel@tonic-gate * the libc versions. This should probably be done as part of an overall
537c478bd9Sstevel@tonic-gate * effort to rid csh of local versions of functions now in libc.
547c478bd9Sstevel@tonic-gate */
557c478bd9Sstevel@tonic-gate
568e3c57a3Sraf static int wstat(int code, int status);
578e3c57a3Sraf
588e3c57a3Sraf pid_t
csh_wait3(int * status,int options,struct rusage * rp)598e3c57a3Sraf csh_wait3(int *status, int options, struct rusage *rp)
607c478bd9Sstevel@tonic-gate {
618e3c57a3Sraf struct tms before_tms;
628e3c57a3Sraf struct tms after_tms;
638e3c57a3Sraf siginfo_t info;
648e3c57a3Sraf int error;
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate if (rp)
678e3c57a3Sraf memset((void *)rp, 0, sizeof (struct rusage));
688e3c57a3Sraf memset((void *)&info, 0, sizeof (siginfo_t));
698e3c57a3Sraf if (times(&before_tms) == -1)
708e3c57a3Sraf return (-1); /* errno is set by times() */
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate * BSD's wait3() only supports WNOHANG & WUNTRACED
747c478bd9Sstevel@tonic-gate */
757c478bd9Sstevel@tonic-gate options |= (WNOHANG|WUNTRACED|WEXITED|WSTOPPED|WTRAPPED|WCONTINUED);
768e3c57a3Sraf error = waitid(P_ALL, 0, &info, options);
778e3c57a3Sraf if (error == 0) {
788e3c57a3Sraf clock_t diffu; /* difference in usertime (ticks) */
798e3c57a3Sraf clock_t diffs; /* difference in systemtime (ticks) */
807c478bd9Sstevel@tonic-gate
818e3c57a3Sraf if ((options & WNOHANG) && (info.si_pid == 0))
828e3c57a3Sraf return (0); /* no child found */
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate if (rp) {
858e3c57a3Sraf if (times(&after_tms) == -1)
868e3c57a3Sraf return (-1); /* errno set by times() */
878e3c57a3Sraf /*
888e3c57a3Sraf * The system/user time is an approximation only !!!
898e3c57a3Sraf */
908e3c57a3Sraf diffu = after_tms.tms_cutime - before_tms.tms_cutime;
918e3c57a3Sraf diffs = after_tms.tms_cstime - before_tms.tms_cstime;
928e3c57a3Sraf rp->ru_utime.tv_sec = diffu/HZ;
93*70a587ddSchin rp->ru_utime.tv_usec = ((diffu % HZ) * 1000000) / HZ;
948e3c57a3Sraf rp->ru_stime.tv_sec = diffs/HZ;
95*70a587ddSchin rp->ru_stime.tv_usec = ((diffs % HZ) * 1000000) / HZ;
967c478bd9Sstevel@tonic-gate }
978e3c57a3Sraf *status = wstat(info.si_code, info.si_status);
988e3c57a3Sraf return (info.si_pid);
997c478bd9Sstevel@tonic-gate
1008e3c57a3Sraf } else {
1018e3c57a3Sraf return (-1); /* error number is set by waitid() */
1028e3c57a3Sraf }
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate /*
1067c478bd9Sstevel@tonic-gate * Convert the status code to old style wait status
1077c478bd9Sstevel@tonic-gate */
1088e3c57a3Sraf static int
wstat(int code,int status)1098e3c57a3Sraf wstat(int code, int status)
1107c478bd9Sstevel@tonic-gate {
1118e3c57a3Sraf int stat = (status & 0377);
1128e3c57a3Sraf
1138e3c57a3Sraf switch (code) {
1148e3c57a3Sraf case CLD_EXITED:
1158e3c57a3Sraf stat <<= 8;
1168e3c57a3Sraf break;
1178e3c57a3Sraf case CLD_DUMPED:
1188e3c57a3Sraf stat |= WCOREFLG;
1198e3c57a3Sraf break;
1208e3c57a3Sraf case CLD_KILLED:
1218e3c57a3Sraf break;
1228e3c57a3Sraf case CLD_TRAPPED:
1238e3c57a3Sraf case CLD_STOPPED:
1248e3c57a3Sraf stat <<= 8;
1258e3c57a3Sraf stat |= WSTOPFLG;
1268e3c57a3Sraf break;
1277c478bd9Sstevel@tonic-gate case CLD_CONTINUED:
1288e3c57a3Sraf stat = WCONTFLG;
1298e3c57a3Sraf break;
1308e3c57a3Sraf }
1318e3c57a3Sraf return (stat);
1328e3c57a3Sraf }
1338e3c57a3Sraf
1348e3c57a3Sraf pid_t
csh_wait_noreap(void)1358e3c57a3Sraf csh_wait_noreap(void)
1368e3c57a3Sraf {
1378e3c57a3Sraf siginfo_t info;
1388e3c57a3Sraf
1398e3c57a3Sraf if (waitid(P_ALL, 0, &info,
1408e3c57a3Sraf WEXITED | WTRAPPED | WSTOPPED | WCONTINUED | WNOWAIT) != 0)
1418e3c57a3Sraf return (-1);
1428e3c57a3Sraf return (info.si_pid);
1437c478bd9Sstevel@tonic-gate }
144