2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
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.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 * Compatibility lib for BSD's wait3(). It is not
19 * binary compatible, since BSD's WNOHANG and WUNTRACED
20 * carry different #define values.
23 #include <sys/types.h>
25 #include <sys/times.h>
27 #include <sys/siginfo.h>
28 #include <sys/procset.h>
29 #include <sys/param.h>
30 #include <sys/resource.h>
33 * Since sysV does not support rusage as in BSD, an approximate approach
38 * if ( a child is found )
40 * rusage ~= diff in the 2 times call
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.
58 static int wstat(int code
, int status
);
61 csh_wait3(int *status
, int options
, struct rusage
*rp
)
63 struct tms before_tms
;
69 memset(rp
, 0, sizeof (struct rusage
));
70 memset(&info
, 0, sizeof (siginfo_t
));
71 if (times(&before_tms
) == -1)
72 return (-1); /* errno is set by times() */
75 * BSD's wait3() only supports WNOHANG & WUNTRACED
77 options
|= (WNOHANG
|WUNTRACED
|WEXITED
|WSTOPPED
|WTRAPPED
|WCONTINUED
);
78 error
= waitid(P_ALL
, 0, &info
, options
);
80 clock_t diffu
; /* difference in usertime (ticks) */
81 clock_t diffs
; /* difference in systemtime (ticks) */
83 if ((options
& WNOHANG
) && (info
.si_pid
== 0))
84 return (0); /* no child found */
87 if (times(&after_tms
) == -1)
88 return (-1); /* errno set by times() */
90 * The system/user time is an approximation only !!!
92 diffu
= after_tms
.tms_cutime
- before_tms
.tms_cutime
;
93 diffs
= after_tms
.tms_cstime
- before_tms
.tms_cstime
;
94 rp
->ru_utime
.tv_sec
= diffu
/HZ
;
95 rp
->ru_utime
.tv_usec
= ((diffu
% HZ
) * 1000000) / HZ
;
96 rp
->ru_stime
.tv_sec
= diffs
/HZ
;
97 rp
->ru_stime
.tv_usec
= ((diffs
% HZ
) * 1000000) / HZ
;
99 *status
= wstat(info
.si_code
, info
.si_status
);
100 return (info
.si_pid
);
103 return (-1); /* error number is set by waitid() */
108 * Convert the status code to old style wait status
111 wstat(int code
, int status
)
113 int stat
= (status
& 0377);
137 csh_wait_noreap(void)
141 if (waitid(P_ALL
, 0, &info
,
142 WEXITED
| WTRAPPED
| WSTOPPED
| WCONTINUED
| WNOWAIT
) != 0)
144 return (info
.si_pid
);