17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*
237c478bdstevel@tonic-gate * Copyright (c) 1995-1997, by Sun Microsystems, Inc.
247c478bdstevel@tonic-gate * All rights reserved.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bdstevel@tonic-gate/*	  All Rights Reserved  	*/
297c478bdstevel@tonic-gate
307c478bdstevel@tonic-gate
317c478bdstevel@tonic-gate/* 	Portions Copyright(c) 1988, Sun Microsystems Inc.	*/
327c478bdstevel@tonic-gate/*	All Rights Reserved					*/
337c478bdstevel@tonic-gate
347c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.1	*/
357c478bdstevel@tonic-gate
367c478bdstevel@tonic-gate/*LINTLIBRARY*/
377c478bdstevel@tonic-gate
387c478bdstevel@tonic-gate/*
397c478bdstevel@tonic-gate * Compatibility lib for SunOS's wait4().
407c478bdstevel@tonic-gate */
417c478bdstevel@tonic-gate
427c478bdstevel@tonic-gate#include <sys/types.h>
437c478bdstevel@tonic-gate#include <sys/time.h>
447c478bdstevel@tonic-gate#include <sys/times.h>
457c478bdstevel@tonic-gate#include <sys/wait.h>
467c478bdstevel@tonic-gate#include <sys/siginfo.h>
477c478bdstevel@tonic-gate#include <sys/procset.h>
487c478bdstevel@tonic-gate#include <sys/param.h>
497c478bdstevel@tonic-gate#include <sys/resource.h>
507c478bdstevel@tonic-gate#include <unistd.h>
517c478bdstevel@tonic-gate#include <string.h>
527c478bdstevel@tonic-gate#include <errno.h>
537c478bdstevel@tonic-gate
547c478bdstevel@tonic-gate/*
557c478bdstevel@tonic-gate * Since sysV does not support rusage as in BSD, an approximate approach
567c478bdstevel@tonic-gate * is:
577c478bdstevel@tonic-gate *      ...
587c478bdstevel@tonic-gate *      call times
597c478bdstevel@tonic-gate *      call waitid
607c478bdstevel@tonic-gate *      if ( a child is found )
617c478bdstevel@tonic-gate *              call times again
627c478bdstevel@tonic-gate *              rusage ~= diff in the 2 times call
637c478bdstevel@tonic-gate *      ...
647c478bdstevel@tonic-gate */
657c478bdstevel@tonic-gate
667c478bdstevel@tonic-gate/*
677c478bdstevel@tonic-gate * forward declaration
687c478bdstevel@tonic-gate */
697c478bdstevel@tonic-gatestatic int wstat(int, int);
707c478bdstevel@tonic-gate
717c478bdstevel@tonic-gatepid_t
727c478bdstevel@tonic-gatewait4(pid_t pid, int *status, int options, struct rusage *rp)
737c478bdstevel@tonic-gate{
747c478bdstevel@tonic-gate	struct  tms	before_tms;
757c478bdstevel@tonic-gate	struct  tms	after_tms;
767c478bdstevel@tonic-gate	siginfo_t	info;
777c478bdstevel@tonic-gate	int		error;
787c478bdstevel@tonic-gate	int 		noptions;
797c478bdstevel@tonic-gate	idtype_t	idtype;
807c478bdstevel@tonic-gate
817c478bdstevel@tonic-gate	if ((long)status == -1L || (long)rp == -1L) {
827c478bdstevel@tonic-gate		errno = EFAULT;
837c478bdstevel@tonic-gate		return (-1);
847c478bdstevel@tonic-gate	}
857c478bdstevel@tonic-gate
867c478bdstevel@tonic-gate	if (rp)
877c478bdstevel@tonic-gate		(void) memset(rp, 0, sizeof (struct rusage));
887c478bdstevel@tonic-gate	(void) memset(&info, 0, sizeof (siginfo_t));
897c478bdstevel@tonic-gate	if (times(&before_tms) < 0)
907c478bdstevel@tonic-gate		return (-1);	/* errno is set by times() */
917c478bdstevel@tonic-gate
927c478bdstevel@tonic-gate	/*
937c478bdstevel@tonic-gate	 * SunOS's wait4() only supports WNOHANG & WUNTRACED
947c478bdstevel@tonic-gate	 */
957c478bdstevel@tonic-gate	if (options & ~(WNOHANG|WUNTRACED))
967c478bdstevel@tonic-gate		return (EINVAL);	/* used to be done by the kernel */
977c478bdstevel@tonic-gate	noptions = options | WEXITED | WTRAPPED;
987c478bdstevel@tonic-gate
997c478bdstevel@tonic-gate	/*
1007c478bdstevel@tonic-gate	 * Emulate undocumented 4.x semantics for 1186845
1017c478bdstevel@tonic-gate	 */
1027c478bdstevel@tonic-gate	if (pid < 0) {
1037c478bdstevel@tonic-gate		pid = -pid;
1047c478bdstevel@tonic-gate		idtype = P_PGID;
1057c478bdstevel@tonic-gate	} else if (pid == 0)
1067c478bdstevel@tonic-gate		idtype = P_ALL;
1077c478bdstevel@tonic-gate	else
1087c478bdstevel@tonic-gate		idtype = P_PID;
1097c478bdstevel@tonic-gate
1107c478bdstevel@tonic-gate	error = waitid(idtype, pid, &info, noptions);
1117c478bdstevel@tonic-gate	if (error == 0) {
1127c478bdstevel@tonic-gate		clock_t	diffu;  /* difference in usertime (ticks) */
1137c478bdstevel@tonic-gate		clock_t	diffs;  /* difference in systemtime (ticks) */
1147c478bdstevel@tonic-gate
1157c478bdstevel@tonic-gate		if ((options & WNOHANG) && (info.si_pid == 0))
1167c478bdstevel@tonic-gate			return (0);	/* no child found */
1177c478bdstevel@tonic-gate
1187c478bdstevel@tonic-gate		if (rp) {
1197c478bdstevel@tonic-gate			if (times(&after_tms) < 0)
1207c478bdstevel@tonic-gate				return (-1);    /* errno set by times() */
1217c478bdstevel@tonic-gate			/*
1227c478bdstevel@tonic-gate			 * The system/user time is an approximation only !!!
1237c478bdstevel@tonic-gate			 */
1247c478bdstevel@tonic-gate			diffu = after_tms.tms_cutime - before_tms.tms_cutime;
1257c478bdstevel@tonic-gate			diffs = after_tms.tms_cstime - before_tms.tms_cstime;
1267c478bdstevel@tonic-gate			rp->ru_utime.tv_sec = diffu / HZ;
1277c478bdstevel@tonic-gate			rp->ru_utime.tv_usec = (diffu % HZ) * (1000000 / HZ);
1287c478bdstevel@tonic-gate			rp->ru_stime.tv_sec = diffs/ HZ;
1297c478bdstevel@tonic-gate			rp->ru_stime.tv_usec = (diffs % HZ) * (1000000 / HZ);
1307c478bdstevel@tonic-gate		}
1317c478bdstevel@tonic-gate		if (status)
1327c478bdstevel@tonic-gate			*status = wstat(info.si_code, info.si_status);
1337c478bdstevel@tonic-gate		return (info.si_pid);
1347c478bdstevel@tonic-gate	} else {
1357c478bdstevel@tonic-gate		return (-1);		/* error number is set by waitid() */
1367c478bdstevel@tonic-gate	}
1377c478bdstevel@tonic-gate}
1387c478bdstevel@tonic-gate
1397c478bdstevel@tonic-gate/*
1407c478bdstevel@tonic-gate * Convert the status code to old style wait status
1417c478bdstevel@tonic-gate */
1427c478bdstevel@tonic-gatestatic int
1437c478bdstevel@tonic-gatewstat(int code, int status)
1447c478bdstevel@tonic-gate{
1457c478bdstevel@tonic-gate	int stat = (status & 0377);
1467c478bdstevel@tonic-gate
1477c478bdstevel@tonic-gate	switch (code) {
1487c478bdstevel@tonic-gate	case CLD_EXITED:
1497c478bdstevel@tonic-gate		stat <<= 8;
1507c478bdstevel@tonic-gate		break;
1517c478bdstevel@tonic-gate	case CLD_DUMPED:
1527c478bdstevel@tonic-gate		stat |= WCOREFLG;
1537c478bdstevel@tonic-gate		break;
1547c478bdstevel@tonic-gate	case CLD_KILLED:
1557c478bdstevel@tonic-gate		break;
1567c478bdstevel@tonic-gate	case CLD_TRAPPED:
1577c478bdstevel@tonic-gate	case CLD_STOPPED:
1587c478bdstevel@tonic-gate		stat <<= 8;
1597c478bdstevel@tonic-gate		stat |= WSTOPFLG;
1607c478bdstevel@tonic-gate		break;
1617c478bdstevel@tonic-gate	case CLD_CONTINUED:
1627c478bdstevel@tonic-gate		stat = WCONTFLG;
1637c478bdstevel@tonic-gate		break;
1647c478bdstevel@tonic-gate	}
1657c478bdstevel@tonic-gate	return (stat);
1667c478bdstevel@tonic-gate}
167