0
|
1 /*
|
|
2 * Copyright 2006 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 "@(#)wait3.c 1.8 06/06/12 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 static int wstat(int code, int status);
|
|
59
|
|
60 pid_t
|
|
61 csh_wait3(int *status, int options, struct rusage *rp)
|
|
62 {
|
|
63 struct tms before_tms;
|
|
64 struct tms after_tms;
|
|
65 siginfo_t info;
|
|
66 int error;
|
|
67
|
|
68 if (rp)
|
|
69 memset((void *)rp, 0, sizeof (struct rusage));
|
|
70 memset((void *)&info, 0, sizeof (siginfo_t));
|
|
71 if (times(&before_tms) == -1)
|
|
72 return (-1); /* errno is set by times() */
|
|
73
|
|
74 /*
|
|
75 * BSD's wait3() only supports WNOHANG & WUNTRACED
|
|
76 */
|
|
77 options |= (WNOHANG|WUNTRACED|WEXITED|WSTOPPED|WTRAPPED|WCONTINUED);
|
|
78 error = waitid(P_ALL, 0, &info, options);
|
|
79 if (error == 0) {
|
|
80 clock_t diffu; /* difference in usertime (ticks) */
|
|
81 clock_t diffs; /* difference in systemtime (ticks) */
|
|
82
|
|
83 if ((options & WNOHANG) && (info.si_pid == 0))
|
|
84 return (0); /* no child found */
|
|
85
|
|
86 if (rp) {
|
|
87 if (times(&after_tms) == -1)
|
|
88 return (-1); /* errno set by times() */
|
|
89 /*
|
|
90 * The system/user time is an approximation only !!!
|
|
91 */
|
|
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;
|
|
98 }
|
|
99 *status = wstat(info.si_code, info.si_status);
|
|
100 return (info.si_pid);
|
|
101
|
|
102 } else {
|
|
103 return (-1); /* error number is set by waitid() */
|
|
104 }
|
|
105 }
|
|
106
|
|
107 /*
|
|
108 * Convert the status code to old style wait status
|
|
109 */
|
|
110 static int
|
|
111 wstat(int code, int status)
|
|
112 {
|
|
113 int stat = (status & 0377);
|
|
114
|
|
115 switch (code) {
|
|
116 case CLD_EXITED:
|
|
117 stat <<= 8;
|
|
118 break;
|
|
119 case CLD_DUMPED:
|
|
120 stat |= WCOREFLG;
|
|
121 break;
|
|
122 case CLD_KILLED:
|
|
123 break;
|
|
124 case CLD_TRAPPED:
|
|
125 case CLD_STOPPED:
|
|
126 stat <<= 8;
|
|
127 stat |= WSTOPFLG;
|
|
128 break;
|
|
129 case CLD_CONTINUED:
|
|
130 stat = WCONTFLG;
|
|
131 break;
|
|
132 }
|
|
133 return (stat);
|
|
134 }
|
|
135
|
|
136 pid_t
|
|
137 csh_wait_noreap(void)
|
|
138 {
|
|
139 siginfo_t info;
|
|
140
|
|
141 if (waitid(P_ALL, 0, &info,
|
|
142 WEXITED | WTRAPPED | WSTOPPED | WCONTINUED | WNOWAIT) != 0)
|
|
143 return (-1);
|
|
144 return (info.si_pid);
|
|
145 }
|