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