xref: /illumos-gate/usr/src/cmd/priocntl/subr.c (revision d2a70789)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include	<stdio.h>
327c478bd9Sstevel@tonic-gate #include	<string.h>
337c478bd9Sstevel@tonic-gate #include	<strings.h>
347c478bd9Sstevel@tonic-gate #include	<stdlib.h>
357c478bd9Sstevel@tonic-gate #include	<unistd.h>
367c478bd9Sstevel@tonic-gate #include	<sys/types.h>
377c478bd9Sstevel@tonic-gate #include	<limits.h>
387c478bd9Sstevel@tonic-gate #include	<dirent.h>
397c478bd9Sstevel@tonic-gate #include	<fcntl.h>
407c478bd9Sstevel@tonic-gate #include	<sys/time.h>
417c478bd9Sstevel@tonic-gate #include	<sys/procset.h>
427c478bd9Sstevel@tonic-gate #include	<sys/priocntl.h>
437c478bd9Sstevel@tonic-gate #include	<sys/task.h>
447c478bd9Sstevel@tonic-gate #include	<procfs.h>
457c478bd9Sstevel@tonic-gate #include	<project.h>
467c478bd9Sstevel@tonic-gate #include	<errno.h>
477c478bd9Sstevel@tonic-gate #include	<zone.h>
487c478bd9Sstevel@tonic-gate #include	<libcontract_priv.h>
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #include "priocntl.h"
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate  * Utility functions for priocntl command.
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate static char	*procdir = "/proc";
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
617c478bd9Sstevel@tonic-gate void
fatalerr(format,a1,a2,a3,a4,a5)627c478bd9Sstevel@tonic-gate fatalerr(format, a1, a2, a3, a4, a5)
637c478bd9Sstevel@tonic-gate char	*format;
647c478bd9Sstevel@tonic-gate int	a1, a2, a3, a4, a5;
657c478bd9Sstevel@tonic-gate {
667c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, format, a1, a2, a3, a4, a5);
677c478bd9Sstevel@tonic-gate 	exit(1);
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  * Structure defining idtypes known to the priocntl command
73*d2a70789SRichard Lowe  * along with the corresponding names
747c478bd9Sstevel@tonic-gate  * The idtype values themselves are defined in <sys/procset.h>.
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate static struct idtypes {
777c478bd9Sstevel@tonic-gate 	idtype_t	idtype;
787c478bd9Sstevel@tonic-gate 	char		*idtypnm;
797c478bd9Sstevel@tonic-gate } idtypes [] = {
807c478bd9Sstevel@tonic-gate 	{ P_PID,	"pid"	},
817c478bd9Sstevel@tonic-gate 	{ P_PPID,	"ppid"	},
827c478bd9Sstevel@tonic-gate 	{ P_PGID,	"pgid"	},
837c478bd9Sstevel@tonic-gate 	{ P_SID,	"sid"	},
847c478bd9Sstevel@tonic-gate 	{ P_CID,	"class"	},
857c478bd9Sstevel@tonic-gate 	{ P_UID,	"uid"	},
867c478bd9Sstevel@tonic-gate 	{ P_GID,	"gid"	},
877c478bd9Sstevel@tonic-gate 	{ P_PROJID,	"projid" },
887c478bd9Sstevel@tonic-gate 	{ P_TASKID,	"taskid" },
897c478bd9Sstevel@tonic-gate 	{ P_ZONEID,	"zoneid" },
907c478bd9Sstevel@tonic-gate 	{ P_CTID,	"ctid" },
917c478bd9Sstevel@tonic-gate 	{ P_ALL,	"all"	}
927c478bd9Sstevel@tonic-gate };
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate #define	IDCNT	(sizeof (idtypes) / sizeof (struct idtypes))
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate int
str2idtyp(idtypnm,idtypep)987c478bd9Sstevel@tonic-gate str2idtyp(idtypnm, idtypep)
997c478bd9Sstevel@tonic-gate char		*idtypnm;
1007c478bd9Sstevel@tonic-gate idtype_t	*idtypep;
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 	register struct idtypes	*curp;
1037c478bd9Sstevel@tonic-gate 	register struct idtypes	*endp;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	for (curp = idtypes, endp = &idtypes[IDCNT]; curp < endp; curp++) {
1067c478bd9Sstevel@tonic-gate 		if (strcmp(curp->idtypnm, idtypnm) == 0) {
1077c478bd9Sstevel@tonic-gate 			*idtypep = curp->idtype;
1087c478bd9Sstevel@tonic-gate 			return (0);
1097c478bd9Sstevel@tonic-gate 		}
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 	return (-1);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate int
idtyp2str(idtype,idtypnm)1167c478bd9Sstevel@tonic-gate idtyp2str(idtype, idtypnm)
1177c478bd9Sstevel@tonic-gate idtype_t	idtype;
1187c478bd9Sstevel@tonic-gate char		*idtypnm;
1197c478bd9Sstevel@tonic-gate {
1207c478bd9Sstevel@tonic-gate 	register struct idtypes	*curp;
1217c478bd9Sstevel@tonic-gate 	register struct idtypes	*endp;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	for (curp = idtypes, endp = &idtypes[IDCNT]; curp < endp; curp++) {
1247c478bd9Sstevel@tonic-gate 		if (idtype == curp->idtype) {
1257c478bd9Sstevel@tonic-gate 			(void) strncpy(idtypnm, curp->idtypnm, PC_IDTYPNMSZ);
1267c478bd9Sstevel@tonic-gate 			return (0);
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 	return (-1);
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate  * Compare two IDs for equality.
1357c478bd9Sstevel@tonic-gate  */
1367c478bd9Sstevel@tonic-gate int
idcompar(id1p,id2p)1377c478bd9Sstevel@tonic-gate idcompar(id1p, id2p)
1387c478bd9Sstevel@tonic-gate id_t	*id1p;
1397c478bd9Sstevel@tonic-gate id_t	*id2p;
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate 	if (*id1p == *id2p)
1427c478bd9Sstevel@tonic-gate 		return (0);
1437c478bd9Sstevel@tonic-gate 	else
1447c478bd9Sstevel@tonic-gate 		return (-1);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate id_t
clname2cid(clname)1497c478bd9Sstevel@tonic-gate clname2cid(clname)
1507c478bd9Sstevel@tonic-gate char	*clname;
1517c478bd9Sstevel@tonic-gate {
1527c478bd9Sstevel@tonic-gate 	pcinfo_t	pcinfo;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	(void) strncpy(pcinfo.pc_clname, clname, PC_CLNMSZ);
1557c478bd9Sstevel@tonic-gate 	if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1)
1567c478bd9Sstevel@tonic-gate 		return ((id_t)-1);
1577c478bd9Sstevel@tonic-gate 	return (pcinfo.pc_cid);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate int
getmyid(idtype,idptr)1627c478bd9Sstevel@tonic-gate getmyid(idtype, idptr)
1637c478bd9Sstevel@tonic-gate idtype_t	idtype;
1647c478bd9Sstevel@tonic-gate id_t		*idptr;
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate 	pcinfo_t	pcinfo;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	switch (idtype) {
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	case P_PID:
1717c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getpid();
1727c478bd9Sstevel@tonic-gate 		break;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	case P_PPID:
1757c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getppid();
1767c478bd9Sstevel@tonic-gate 		break;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	case P_PGID:
1797c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getpgrp();
1807c478bd9Sstevel@tonic-gate 		break;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	case P_SID:
1837c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getsid(getpid());
1847c478bd9Sstevel@tonic-gate 		break;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	case P_CID:
1877c478bd9Sstevel@tonic-gate 		if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL,
1887c478bd9Sstevel@tonic-gate 		    PC_KY_CLNAME, pcinfo.pc_clname, 0) == -1 ||
1897c478bd9Sstevel@tonic-gate 		    priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1)
1907c478bd9Sstevel@tonic-gate 			return (-1);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 		*idptr = pcinfo.pc_cid;
1937c478bd9Sstevel@tonic-gate 		break;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	case P_UID:
1967c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getuid();
1977c478bd9Sstevel@tonic-gate 		break;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	case P_GID:
2007c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getgid();
2017c478bd9Sstevel@tonic-gate 		break;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	case P_PROJID:
2047c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getprojid();
2057c478bd9Sstevel@tonic-gate 		break;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	case P_TASKID:
2087c478bd9Sstevel@tonic-gate 		*idptr = (id_t)gettaskid();
2097c478bd9Sstevel@tonic-gate 		break;
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	case P_ZONEID:
2127c478bd9Sstevel@tonic-gate 		*idptr = (id_t)getzoneid();
2137c478bd9Sstevel@tonic-gate 		break;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	case P_CTID: {
2167c478bd9Sstevel@tonic-gate 		ctid_t id = getctid();
2177c478bd9Sstevel@tonic-gate 		if (id == -1)
2187c478bd9Sstevel@tonic-gate 			return (-1);
2197c478bd9Sstevel@tonic-gate 		*idptr = id;
2207c478bd9Sstevel@tonic-gate 		break;
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	default:
2247c478bd9Sstevel@tonic-gate 		return (-1);
2257c478bd9Sstevel@tonic-gate 	}
2267c478bd9Sstevel@tonic-gate 	return (0);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate int
getmyidstr(idtype,idstr)2317c478bd9Sstevel@tonic-gate getmyidstr(idtype, idstr)
2327c478bd9Sstevel@tonic-gate idtype_t	idtype;
2337c478bd9Sstevel@tonic-gate char		*idstr;
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate 	char		clname[PC_CLNMSZ];
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	switch (idtype) {
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	case P_PID:
2407c478bd9Sstevel@tonic-gate 		itoa((long)getpid(), idstr);
2417c478bd9Sstevel@tonic-gate 		break;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	case P_PPID:
2447c478bd9Sstevel@tonic-gate 		itoa((long)getppid(), idstr);
2457c478bd9Sstevel@tonic-gate 		break;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	case P_PGID:
2487c478bd9Sstevel@tonic-gate 		itoa((long)getpgrp(), idstr);
2497c478bd9Sstevel@tonic-gate 		break;
2507c478bd9Sstevel@tonic-gate 	case P_SID:
2517c478bd9Sstevel@tonic-gate 		itoa((long)getsid(getpid()), idstr);
2527c478bd9Sstevel@tonic-gate 		break;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	case P_CID:
2557c478bd9Sstevel@tonic-gate 		if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL,
2567c478bd9Sstevel@tonic-gate 		    PC_KY_CLNAME, clname, 0) == -1)
2577c478bd9Sstevel@tonic-gate 			return (-1);
2587c478bd9Sstevel@tonic-gate 		(void) strncpy(idstr, clname, PC_CLNMSZ);
2597c478bd9Sstevel@tonic-gate 		break;
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	case P_UID:
2627c478bd9Sstevel@tonic-gate 		itoa((long)getuid(), idstr);
2637c478bd9Sstevel@tonic-gate 		break;
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	case P_GID:
2667c478bd9Sstevel@tonic-gate 		itoa((long)getgid(), idstr);
2677c478bd9Sstevel@tonic-gate 		break;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	case P_PROJID:
2707c478bd9Sstevel@tonic-gate 		itoa((long)getprojid(), idstr);
2717c478bd9Sstevel@tonic-gate 		break;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	case P_TASKID:
2747c478bd9Sstevel@tonic-gate 		itoa((long)gettaskid(), idstr);
2757c478bd9Sstevel@tonic-gate 		break;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	case P_ZONEID:
2787c478bd9Sstevel@tonic-gate 		itoa((long)getzoneid(), idstr);
2797c478bd9Sstevel@tonic-gate 		break;
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	case P_CTID: {
2827c478bd9Sstevel@tonic-gate 		id_t id;
2837c478bd9Sstevel@tonic-gate 		if ((id = getctid()) == -1)
2847c478bd9Sstevel@tonic-gate 			return (-1);
2857c478bd9Sstevel@tonic-gate 		itoa((long)id, idstr);
2867c478bd9Sstevel@tonic-gate 		break;
2877c478bd9Sstevel@tonic-gate 	}
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	default:
2907c478bd9Sstevel@tonic-gate 		return (-1);
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 	return (0);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate /*
2967c478bd9Sstevel@tonic-gate  * Look for pids with "upri > uprilim" in the set specified by idtype/id.
2977c478bd9Sstevel@tonic-gate  * If upri exceeds uprilim then print a warning.
2987c478bd9Sstevel@tonic-gate  */
2997c478bd9Sstevel@tonic-gate int
verifyupri(idtype_t idtype,id_t id,char * clname,int key,pri_t upri,char * basenm)3007c478bd9Sstevel@tonic-gate verifyupri(idtype_t idtype, id_t id, char *clname, int key,
3017c478bd9Sstevel@tonic-gate 	pri_t upri, char *basenm)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate 	psinfo_t		prinfo;
3047c478bd9Sstevel@tonic-gate 	prcred_t		prcred;
3057c478bd9Sstevel@tonic-gate 	DIR			*dirp;
3067c478bd9Sstevel@tonic-gate 	struct dirent		*dentp;
3077c478bd9Sstevel@tonic-gate 	char			pname[MAXNAMLEN];
3087c478bd9Sstevel@tonic-gate 	char			*fname;
3097c478bd9Sstevel@tonic-gate 	int			procfd;
3107c478bd9Sstevel@tonic-gate 	int			saverr;
3117c478bd9Sstevel@tonic-gate 	pri_t			uprilim;
3127c478bd9Sstevel@tonic-gate 	int			verify;
3137c478bd9Sstevel@tonic-gate 	int			error = 0;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (idtype == P_PID) {
3167c478bd9Sstevel@tonic-gate 		if (priocntl(P_PID, id, PC_GETXPARMS, clname, key,
3177c478bd9Sstevel@tonic-gate 		    &uprilim, 0) == -1)
3187c478bd9Sstevel@tonic-gate 			error = -1;
3197c478bd9Sstevel@tonic-gate 		else if (upri > uprilim)
3207c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3217c478bd9Sstevel@tonic-gate 			    "%s: Specified user priority %d exceeds"
3227c478bd9Sstevel@tonic-gate 			    " limit %d; set to %d (pid %d)\n",
3237c478bd9Sstevel@tonic-gate 			    basenm, upri, uprilim, uprilim, (int)id);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 		return (error);
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	/*
3297c478bd9Sstevel@tonic-gate 	 * Look for the processes in the set specified by idtype/id.
3307c478bd9Sstevel@tonic-gate 	 * We read the /proc/<pid>/psinfo file to get the necessary
3317c478bd9Sstevel@tonic-gate 	 * process information.
3327c478bd9Sstevel@tonic-gate 	 */
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	if ((dirp = opendir(procdir)) == NULL)
3357c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't open PROC directory %s\n",
3367c478bd9Sstevel@tonic-gate 		    basenm, procdir);
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	while ((dentp = readdir(dirp)) != NULL) {
3397c478bd9Sstevel@tonic-gate 		if (dentp->d_name[0] == '.')	/* skip . and .. */
3407c478bd9Sstevel@tonic-gate 			continue;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 		(void) snprintf(pname, MAXNAMLEN, "%s/%s/",
3437c478bd9Sstevel@tonic-gate 		    procdir, dentp->d_name);
3447c478bd9Sstevel@tonic-gate 		fname = pname + strlen(pname);
3457c478bd9Sstevel@tonic-gate retry:
3467c478bd9Sstevel@tonic-gate 		(void) strncpy(fname, "psinfo", strlen("psinfo") + 1);
3477c478bd9Sstevel@tonic-gate 		if ((procfd = open(pname, O_RDONLY)) < 0)
3487c478bd9Sstevel@tonic-gate 			continue;
3497c478bd9Sstevel@tonic-gate 		if (read(procfd, &prinfo, sizeof (prinfo)) != sizeof (prinfo)) {
3507c478bd9Sstevel@tonic-gate 			saverr = errno;
3517c478bd9Sstevel@tonic-gate 			(void) close(procfd);
3527c478bd9Sstevel@tonic-gate 			if (saverr == EAGAIN)
3537c478bd9Sstevel@tonic-gate 				goto retry;
3547c478bd9Sstevel@tonic-gate 			continue;
3557c478bd9Sstevel@tonic-gate 		}
3567c478bd9Sstevel@tonic-gate 		(void) close(procfd);
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 		if (idtype == P_UID || idtype == P_GID) {
3597c478bd9Sstevel@tonic-gate 			(void) strncpy(fname, "cred", strlen("cred") + 1);
3607c478bd9Sstevel@tonic-gate 			if ((procfd = open(pname, O_RDONLY)) < 0 ||
3617c478bd9Sstevel@tonic-gate 			    read(procfd, &prcred, sizeof (prcred)) !=
3627c478bd9Sstevel@tonic-gate 			    sizeof (prcred)) {
3637c478bd9Sstevel@tonic-gate 				saverr = errno;
3647c478bd9Sstevel@tonic-gate 				(void) close(procfd);
3657c478bd9Sstevel@tonic-gate 				if (saverr == EAGAIN)
3667c478bd9Sstevel@tonic-gate 					goto retry;
3677c478bd9Sstevel@tonic-gate 				continue;
3687c478bd9Sstevel@tonic-gate 			}
3697c478bd9Sstevel@tonic-gate 			(void) close(procfd);
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 		if (prinfo.pr_lwp.pr_state == 0 || prinfo.pr_nlwp == 0)
3737c478bd9Sstevel@tonic-gate 			continue;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 		/*
3767c478bd9Sstevel@tonic-gate 		 * The lwp must be in the correct class.
3777c478bd9Sstevel@tonic-gate 		 */
3787c478bd9Sstevel@tonic-gate 		if (strncmp(clname, prinfo.pr_lwp.pr_clname, PC_CLNMSZ) != 0)
3797c478bd9Sstevel@tonic-gate 			continue;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 		verify = 0;
3827c478bd9Sstevel@tonic-gate 		switch (idtype) {
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 		case P_PPID:
3857c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_ppid)
3867c478bd9Sstevel@tonic-gate 				verify++;
3877c478bd9Sstevel@tonic-gate 			break;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 		case P_PGID:
3907c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_pgid)
3917c478bd9Sstevel@tonic-gate 				verify++;
3927c478bd9Sstevel@tonic-gate 			break;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 		case P_SID:
3957c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_sid)
3967c478bd9Sstevel@tonic-gate 				verify++;
3977c478bd9Sstevel@tonic-gate 			break;
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 		case P_UID:
4007c478bd9Sstevel@tonic-gate 			if (id == (id_t)prcred.pr_euid)
4017c478bd9Sstevel@tonic-gate 				verify++;
4027c478bd9Sstevel@tonic-gate 			break;
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 		case P_GID:
4057c478bd9Sstevel@tonic-gate 			if (id == (id_t)prcred.pr_egid)
4067c478bd9Sstevel@tonic-gate 				verify++;
4077c478bd9Sstevel@tonic-gate 			break;
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 		case P_PROJID:
4107c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_projid)
4117c478bd9Sstevel@tonic-gate 				verify++;
4127c478bd9Sstevel@tonic-gate 			break;
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 		case P_TASKID:
4157c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_taskid)
4167c478bd9Sstevel@tonic-gate 				verify++;
4177c478bd9Sstevel@tonic-gate 			break;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 		case P_ZONEID:
4207c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_zoneid)
4217c478bd9Sstevel@tonic-gate 				verify++;
4227c478bd9Sstevel@tonic-gate 			break;
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 		case P_CTID:
4257c478bd9Sstevel@tonic-gate 			if (id == (id_t)prinfo.pr_contract)
4267c478bd9Sstevel@tonic-gate 				verify++;
4277c478bd9Sstevel@tonic-gate 			break;
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate 		case P_CID:
4307c478bd9Sstevel@tonic-gate 		case P_ALL:
4317c478bd9Sstevel@tonic-gate 			verify++;
4327c478bd9Sstevel@tonic-gate 			break;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 		default:
4357c478bd9Sstevel@tonic-gate 			fatalerr("%s: Bad idtype %d in verifyupri()\n",
4367c478bd9Sstevel@tonic-gate 			    basenm, idtype);
4377c478bd9Sstevel@tonic-gate 		}
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 		if (verify) {
4407c478bd9Sstevel@tonic-gate 			if (priocntl(P_PID, prinfo.pr_pid, PC_GETXPARMS,
4417c478bd9Sstevel@tonic-gate 			    clname, key, &uprilim, 0) == -1)
4427c478bd9Sstevel@tonic-gate 				error = -1;
4437c478bd9Sstevel@tonic-gate 			else if (upri > uprilim)
4447c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
4457c478bd9Sstevel@tonic-gate 				    "%s: Specified user priority %d exceeds"
4467c478bd9Sstevel@tonic-gate 				    " limit %d; set to %d (pid %d)\n",
4477c478bd9Sstevel@tonic-gate 				    basenm, upri, uprilim, uprilim,
4487c478bd9Sstevel@tonic-gate 				    (int)prinfo.pr_pid);
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 	}
4517c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	return (error);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate  * Read a list of pids from a stream.
4597c478bd9Sstevel@tonic-gate  */
4607c478bd9Sstevel@tonic-gate pid_t *
read_pidlist(size_t * npidsp,FILE * filep)4617c478bd9Sstevel@tonic-gate read_pidlist(size_t *npidsp, FILE *filep)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate 	size_t	nitems;
4647c478bd9Sstevel@tonic-gate 	pid_t	*pidlist = NULL;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	*npidsp = 0;
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate 	do {
4697c478bd9Sstevel@tonic-gate 		if ((pidlist = (pid_t *)realloc(pidlist,
4707c478bd9Sstevel@tonic-gate 		    (*npidsp + NPIDS) * sizeof (pid_t))) == NULL)
4717c478bd9Sstevel@tonic-gate 			return (NULL);
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate 		nitems = fread(pidlist + *npidsp, sizeof (pid_t), NPIDS, filep);
4747c478bd9Sstevel@tonic-gate 		if (ferror(filep))
4757c478bd9Sstevel@tonic-gate 			return (NULL);
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 		*npidsp += nitems;
4787c478bd9Sstevel@tonic-gate 	} while (nitems == NPIDS);
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	return (pidlist);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate void
free_pidlist(pid_t * pidlist)4857c478bd9Sstevel@tonic-gate free_pidlist(pid_t *pidlist)
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate 	free(pidlist);
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate long
str2num(char * p,long min,long max)4927c478bd9Sstevel@tonic-gate str2num(char *p, long min, long max)
4937c478bd9Sstevel@tonic-gate {
4947c478bd9Sstevel@tonic-gate 	long val;
4957c478bd9Sstevel@tonic-gate 	char *q;
4967c478bd9Sstevel@tonic-gate 	errno = 0;
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	val = strtol(p, &q, 10);
4997c478bd9Sstevel@tonic-gate 	if (errno != 0 || q == p || *q != '\0' || val < min || val > max)
5007c478bd9Sstevel@tonic-gate 		errno = EINVAL;
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	return (val);
5037c478bd9Sstevel@tonic-gate }
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate /*
5077c478bd9Sstevel@tonic-gate  * itoa() and reverse() taken almost verbatim from K & R Chapter 3.
5087c478bd9Sstevel@tonic-gate  */
5097c478bd9Sstevel@tonic-gate static void	reverse();
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate /*
5127c478bd9Sstevel@tonic-gate  * itoa(): Convert n to characters in s.
5137c478bd9Sstevel@tonic-gate  */
5147c478bd9Sstevel@tonic-gate void
itoa(n,s)5157c478bd9Sstevel@tonic-gate itoa(n, s)
5167c478bd9Sstevel@tonic-gate long	n;
5177c478bd9Sstevel@tonic-gate char	*s;
5187c478bd9Sstevel@tonic-gate {
5197c478bd9Sstevel@tonic-gate 	long	i, sign;
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	if ((sign = n) < 0)	/* record sign */
5227c478bd9Sstevel@tonic-gate 		n = -n;		/* make sign positive */
5237c478bd9Sstevel@tonic-gate 	i = 0;
5247c478bd9Sstevel@tonic-gate 	do {	/* generate digits in reverse order */
5257c478bd9Sstevel@tonic-gate 		s[i++] = n % 10 + '0';	/* get next digit */
5267c478bd9Sstevel@tonic-gate 	} while ((n /= 10) > 0);	/* delete it */
5277c478bd9Sstevel@tonic-gate 	if (sign < 0)
5287c478bd9Sstevel@tonic-gate 		s[i++] = '-';
5297c478bd9Sstevel@tonic-gate 	s[i] = '\0';
5307c478bd9Sstevel@tonic-gate 	reverse(s);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate /*
5357c478bd9Sstevel@tonic-gate  * reverse(): Reverse string s in place.
5367c478bd9Sstevel@tonic-gate  */
5377c478bd9Sstevel@tonic-gate static void
reverse(s)5387c478bd9Sstevel@tonic-gate reverse(s)
5397c478bd9Sstevel@tonic-gate char	*s;
5407c478bd9Sstevel@tonic-gate {
5417c478bd9Sstevel@tonic-gate 	int	c, i, j;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 	for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
5447c478bd9Sstevel@tonic-gate 		c = s[i];
5457c478bd9Sstevel@tonic-gate 		s[i] = s[j];
5467c478bd9Sstevel@tonic-gate 		s[j] = (char)c;
5477c478bd9Sstevel@tonic-gate 	}
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate  * The following routine was removed from libc (libc/port/gen/hrtnewres.c).
5537c478bd9Sstevel@tonic-gate  * It has also been added to disadmin, so if you fix it here, you should
5547c478bd9Sstevel@tonic-gate  * also probably fix it there. In the long term, this should be recoded to
5557c478bd9Sstevel@tonic-gate  * not be hrt'ish.
5567c478bd9Sstevel@tonic-gate  */
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate /*
5597c478bd9Sstevel@tonic-gate  *	Convert interval expressed in htp->hrt_res to new_res.
5607c478bd9Sstevel@tonic-gate  *
5617c478bd9Sstevel@tonic-gate  *	Calculate: (interval * new_res) / htp->hrt_res  rounding off as
5627c478bd9Sstevel@tonic-gate  *		specified by round.
5637c478bd9Sstevel@tonic-gate  *
5647c478bd9Sstevel@tonic-gate  *	Note:	All args are assumed to be positive.  If
5657c478bd9Sstevel@tonic-gate  *	the last divide results in something bigger than
5667c478bd9Sstevel@tonic-gate  *	a long, then -1 is returned instead.
5677c478bd9Sstevel@tonic-gate  */
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate int
_hrtnewres(htp,new_res,round)5707c478bd9Sstevel@tonic-gate _hrtnewres(htp, new_res, round)
5717c478bd9Sstevel@tonic-gate register hrtimer_t *htp;
5727c478bd9Sstevel@tonic-gate register ulong_t new_res;
5737c478bd9Sstevel@tonic-gate long round;
5747c478bd9Sstevel@tonic-gate {
5757c478bd9Sstevel@tonic-gate 	register long  interval;
5767c478bd9Sstevel@tonic-gate 	longlong_t	dint;
5777c478bd9Sstevel@tonic-gate 	longlong_t	dto_res;
5787c478bd9Sstevel@tonic-gate 	longlong_t	drem;
5797c478bd9Sstevel@tonic-gate 	longlong_t	dfrom_res;
5807c478bd9Sstevel@tonic-gate 	longlong_t	prod;
5817c478bd9Sstevel@tonic-gate 	longlong_t	quot;
5827c478bd9Sstevel@tonic-gate 	register long	numerator;
5837c478bd9Sstevel@tonic-gate 	register long	result;
5847c478bd9Sstevel@tonic-gate 	ulong_t		modulus;
5857c478bd9Sstevel@tonic-gate 	ulong_t		twomodulus;
5867c478bd9Sstevel@tonic-gate 	long		temp;
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	if (new_res > NANOSEC || htp->hrt_rem < 0)
5897c478bd9Sstevel@tonic-gate 		return (-1);
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	if (htp->hrt_rem >= htp->hrt_res) {
5927c478bd9Sstevel@tonic-gate 		htp->hrt_secs += htp->hrt_rem / htp->hrt_res;
5937c478bd9Sstevel@tonic-gate 		htp->hrt_rem = htp->hrt_rem % htp->hrt_res;
5947c478bd9Sstevel@tonic-gate 	}
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 	interval = htp->hrt_rem;
5977c478bd9Sstevel@tonic-gate 	if (interval == 0) {
5987c478bd9Sstevel@tonic-gate 		htp->hrt_res = new_res;
5997c478bd9Sstevel@tonic-gate 		return (0);
6007c478bd9Sstevel@tonic-gate 	}
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	/*
6037c478bd9Sstevel@tonic-gate 	 *	Try to do the calculations in single precision first
6047c478bd9Sstevel@tonic-gate 	 *	(for speed).  If they overflow, use double precision.
6057c478bd9Sstevel@tonic-gate 	 *	What we want to compute is:
6067c478bd9Sstevel@tonic-gate 	 *
6077c478bd9Sstevel@tonic-gate 	 *		(interval * new_res) / hrt->hrt_res
6087c478bd9Sstevel@tonic-gate 	 */
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	numerator = interval * new_res;
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 	if (numerator / new_res  ==  interval) {
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 		/*
6157c478bd9Sstevel@tonic-gate 		 *	The above multiply didn't give overflow since
6167c478bd9Sstevel@tonic-gate 		 *	the division got back the original number.  Go
6177c478bd9Sstevel@tonic-gate 		 *	ahead and compute the result.
6187c478bd9Sstevel@tonic-gate 		 */
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 		result = numerator / htp->hrt_res;
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 		/*
6237c478bd9Sstevel@tonic-gate 		 *	For HRT_RND, compute the value of:
6247c478bd9Sstevel@tonic-gate 		 *
6257c478bd9Sstevel@tonic-gate 		 *		(interval * new_res) % htp->hrt_res
6267c478bd9Sstevel@tonic-gate 		 *
6277c478bd9Sstevel@tonic-gate 		 *	If it is greater than half of the htp->hrt_res,
6287c478bd9Sstevel@tonic-gate 		 *	then rounding increases the result by 1.
6297c478bd9Sstevel@tonic-gate 		 *
6307c478bd9Sstevel@tonic-gate 		 *	For HRT_RNDUP, we increase the result by 1 if:
6317c478bd9Sstevel@tonic-gate 		 *
6327c478bd9Sstevel@tonic-gate 		 *		result * htp->hrt_res != numerator
6337c478bd9Sstevel@tonic-gate 		 *
6347c478bd9Sstevel@tonic-gate 		 *	because this tells us we truncated when calculating
6357c478bd9Sstevel@tonic-gate 		 *	result above.
6367c478bd9Sstevel@tonic-gate 		 *
6377c478bd9Sstevel@tonic-gate 		 *	We also check for overflow when incrementing result
6387c478bd9Sstevel@tonic-gate 		 *	although this is extremely rare.
6397c478bd9Sstevel@tonic-gate 		 */
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 		if (round == HRT_RND) {
6427c478bd9Sstevel@tonic-gate 			modulus = numerator - result * htp->hrt_res;
6437c478bd9Sstevel@tonic-gate 			if ((twomodulus = 2 * modulus) / 2 == modulus) {
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 				/*
6467c478bd9Sstevel@tonic-gate 				 * No overflow (if we overflow in calculation
6477c478bd9Sstevel@tonic-gate 				 * of twomodulus we fall through and use
6487c478bd9Sstevel@tonic-gate 				 * double precision).
6497c478bd9Sstevel@tonic-gate 				 */
6507c478bd9Sstevel@tonic-gate 				if (twomodulus >= htp->hrt_res) {
6517c478bd9Sstevel@tonic-gate 					temp = result + 1;
6527c478bd9Sstevel@tonic-gate 					if (temp - 1 == result)
6537c478bd9Sstevel@tonic-gate 						result++;
6547c478bd9Sstevel@tonic-gate 					else
6557c478bd9Sstevel@tonic-gate 						return (-1);
6567c478bd9Sstevel@tonic-gate 				}
6577c478bd9Sstevel@tonic-gate 				htp->hrt_res = new_res;
6587c478bd9Sstevel@tonic-gate 				htp->hrt_rem = result;
6597c478bd9Sstevel@tonic-gate 				return (0);
6607c478bd9Sstevel@tonic-gate 			}
6617c478bd9Sstevel@tonic-gate 		} else if (round == HRT_RNDUP) {
6627c478bd9Sstevel@tonic-gate 			if (result * htp->hrt_res != numerator) {
6637c478bd9Sstevel@tonic-gate 				temp = result + 1;
6647c478bd9Sstevel@tonic-gate 				if (temp - 1 == result)
6657c478bd9Sstevel@tonic-gate 					result++;
6667c478bd9Sstevel@tonic-gate 				else
6677c478bd9Sstevel@tonic-gate 					return (-1);
6687c478bd9Sstevel@tonic-gate 			}
6697c478bd9Sstevel@tonic-gate 			htp->hrt_res = new_res;
6707c478bd9Sstevel@tonic-gate 			htp->hrt_rem = result;
6717c478bd9Sstevel@tonic-gate 			return (0);
6727c478bd9Sstevel@tonic-gate 		} else {	/* round == HRT_TRUNC */
6737c478bd9Sstevel@tonic-gate 			htp->hrt_res = new_res;
6747c478bd9Sstevel@tonic-gate 			htp->hrt_rem = result;
6757c478bd9Sstevel@tonic-gate 			return (0);
6767c478bd9Sstevel@tonic-gate 		}
6777c478bd9Sstevel@tonic-gate 	}
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	/*
6807c478bd9Sstevel@tonic-gate 	 *	We would get overflow doing the calculation is
6817c478bd9Sstevel@tonic-gate 	 *	single precision so do it the slow but careful way.
6827c478bd9Sstevel@tonic-gate 	 *
6837c478bd9Sstevel@tonic-gate 	 *	Compute the interval times the resolution we are
6847c478bd9Sstevel@tonic-gate 	 *	going to.
6857c478bd9Sstevel@tonic-gate 	 */
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	dint = interval;
6887c478bd9Sstevel@tonic-gate 	dto_res = new_res;
6897c478bd9Sstevel@tonic-gate 	prod = dint * dto_res;
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	/*
6927c478bd9Sstevel@tonic-gate 	 *	For HRT_RND the result will be equal to:
6937c478bd9Sstevel@tonic-gate 	 *
6947c478bd9Sstevel@tonic-gate 	 *		((interval * new_res) + htp->hrt_res / 2) / htp->hrt_res
6957c478bd9Sstevel@tonic-gate 	 *
6967c478bd9Sstevel@tonic-gate 	 *	and for HRT_RNDUP we use:
6977c478bd9Sstevel@tonic-gate 	 *
6987c478bd9Sstevel@tonic-gate 	 *		((interval * new_res) + htp->hrt_res - 1) / htp->hrt_res
6997c478bd9Sstevel@tonic-gate 	 *
7007c478bd9Sstevel@tonic-gate 	 * 	This is a different but equivalent way of rounding.
7017c478bd9Sstevel@tonic-gate 	 */
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	if (round == HRT_RND) {
7047c478bd9Sstevel@tonic-gate 		drem = htp->hrt_res / 2;
7057c478bd9Sstevel@tonic-gate 		prod = prod + drem;
7067c478bd9Sstevel@tonic-gate 	} else if (round == HRT_RNDUP) {
7077c478bd9Sstevel@tonic-gate 		drem = htp->hrt_res - 1;
7087c478bd9Sstevel@tonic-gate 		prod = prod + drem;
7097c478bd9Sstevel@tonic-gate 	}
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate 	dfrom_res = htp->hrt_res;
7127c478bd9Sstevel@tonic-gate 	quot = prod / dfrom_res;
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 	/*
7157c478bd9Sstevel@tonic-gate 	 *	If the quotient won't fit in a long, then we have
7167c478bd9Sstevel@tonic-gate 	 *	overflow.  Otherwise, return the result.
7177c478bd9Sstevel@tonic-gate 	 */
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	if (quot > UINT_MAX) {
7207c478bd9Sstevel@tonic-gate 		return (-1);
7217c478bd9Sstevel@tonic-gate 	} else {
7227c478bd9Sstevel@tonic-gate 		htp->hrt_res = new_res;
7237c478bd9Sstevel@tonic-gate 		htp->hrt_rem = (int)quot;
7247c478bd9Sstevel@tonic-gate 		return (0);
7257c478bd9Sstevel@tonic-gate 	}
7267c478bd9Sstevel@tonic-gate }
727