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