Mercurial > illumos > onarm
comparison usr/src/cmd/csh/wait3.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
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 } |