1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <string.h> 35*7c478bd9Sstevel@tonic-gate #include <strings.h> 36*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 39*7c478bd9Sstevel@tonic-gate #include <limits.h> 40*7c478bd9Sstevel@tonic-gate #include <dirent.h> 41*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/procset.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/priocntl.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/task.h> 46*7c478bd9Sstevel@tonic-gate #include <procfs.h> 47*7c478bd9Sstevel@tonic-gate #include <project.h> 48*7c478bd9Sstevel@tonic-gate #include <errno.h> 49*7c478bd9Sstevel@tonic-gate #include <zone.h> 50*7c478bd9Sstevel@tonic-gate #include <libcontract_priv.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include "priocntl.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Utility functions for priocntl command. 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate static char *procdir = "/proc"; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 63*7c478bd9Sstevel@tonic-gate void 64*7c478bd9Sstevel@tonic-gate fatalerr(format, a1, a2, a3, a4, a5) 65*7c478bd9Sstevel@tonic-gate char *format; 66*7c478bd9Sstevel@tonic-gate int a1, a2, a3, a4, a5; 67*7c478bd9Sstevel@tonic-gate { 68*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, format, a1, a2, a3, a4, a5); 69*7c478bd9Sstevel@tonic-gate exit(1); 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Structure defining idtypes known to the priocntl command 75*7c478bd9Sstevel@tonic-gate * along with the corresponding names and a liberal guess 76*7c478bd9Sstevel@tonic-gate * of the max number of procs sharing any given ID of that type. 77*7c478bd9Sstevel@tonic-gate * The idtype values themselves are defined in <sys/procset.h>. 78*7c478bd9Sstevel@tonic-gate */ 79*7c478bd9Sstevel@tonic-gate static struct idtypes { 80*7c478bd9Sstevel@tonic-gate idtype_t idtype; 81*7c478bd9Sstevel@tonic-gate char *idtypnm; 82*7c478bd9Sstevel@tonic-gate } idtypes [] = { 83*7c478bd9Sstevel@tonic-gate { P_PID, "pid" }, 84*7c478bd9Sstevel@tonic-gate { P_PPID, "ppid" }, 85*7c478bd9Sstevel@tonic-gate { P_PGID, "pgid" }, 86*7c478bd9Sstevel@tonic-gate { P_SID, "sid" }, 87*7c478bd9Sstevel@tonic-gate { P_CID, "class" }, 88*7c478bd9Sstevel@tonic-gate { P_UID, "uid" }, 89*7c478bd9Sstevel@tonic-gate { P_GID, "gid" }, 90*7c478bd9Sstevel@tonic-gate { P_PROJID, "projid" }, 91*7c478bd9Sstevel@tonic-gate { P_TASKID, "taskid" }, 92*7c478bd9Sstevel@tonic-gate { P_ZONEID, "zoneid" }, 93*7c478bd9Sstevel@tonic-gate { P_CTID, "ctid" }, 94*7c478bd9Sstevel@tonic-gate { P_ALL, "all" } 95*7c478bd9Sstevel@tonic-gate }; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate #define IDCNT (sizeof (idtypes) / sizeof (struct idtypes)) 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate int 101*7c478bd9Sstevel@tonic-gate str2idtyp(idtypnm, idtypep) 102*7c478bd9Sstevel@tonic-gate char *idtypnm; 103*7c478bd9Sstevel@tonic-gate idtype_t *idtypep; 104*7c478bd9Sstevel@tonic-gate { 105*7c478bd9Sstevel@tonic-gate register struct idtypes *curp; 106*7c478bd9Sstevel@tonic-gate register struct idtypes *endp; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate for (curp = idtypes, endp = &idtypes[IDCNT]; curp < endp; curp++) { 109*7c478bd9Sstevel@tonic-gate if (strcmp(curp->idtypnm, idtypnm) == 0) { 110*7c478bd9Sstevel@tonic-gate *idtypep = curp->idtype; 111*7c478bd9Sstevel@tonic-gate return (0); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate return (-1); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate int 119*7c478bd9Sstevel@tonic-gate idtyp2str(idtype, idtypnm) 120*7c478bd9Sstevel@tonic-gate idtype_t idtype; 121*7c478bd9Sstevel@tonic-gate char *idtypnm; 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate register struct idtypes *curp; 124*7c478bd9Sstevel@tonic-gate register struct idtypes *endp; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate for (curp = idtypes, endp = &idtypes[IDCNT]; curp < endp; curp++) { 127*7c478bd9Sstevel@tonic-gate if (idtype == curp->idtype) { 128*7c478bd9Sstevel@tonic-gate (void) strncpy(idtypnm, curp->idtypnm, PC_IDTYPNMSZ); 129*7c478bd9Sstevel@tonic-gate return (0); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate return (-1); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* 137*7c478bd9Sstevel@tonic-gate * Compare two IDs for equality. 138*7c478bd9Sstevel@tonic-gate */ 139*7c478bd9Sstevel@tonic-gate int 140*7c478bd9Sstevel@tonic-gate idcompar(id1p, id2p) 141*7c478bd9Sstevel@tonic-gate id_t *id1p; 142*7c478bd9Sstevel@tonic-gate id_t *id2p; 143*7c478bd9Sstevel@tonic-gate { 144*7c478bd9Sstevel@tonic-gate if (*id1p == *id2p) 145*7c478bd9Sstevel@tonic-gate return (0); 146*7c478bd9Sstevel@tonic-gate else 147*7c478bd9Sstevel@tonic-gate return (-1); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate id_t 152*7c478bd9Sstevel@tonic-gate clname2cid(clname) 153*7c478bd9Sstevel@tonic-gate char *clname; 154*7c478bd9Sstevel@tonic-gate { 155*7c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate (void) strncpy(pcinfo.pc_clname, clname, PC_CLNMSZ); 158*7c478bd9Sstevel@tonic-gate if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 159*7c478bd9Sstevel@tonic-gate return ((id_t)-1); 160*7c478bd9Sstevel@tonic-gate return (pcinfo.pc_cid); 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate int 165*7c478bd9Sstevel@tonic-gate getmyid(idtype, idptr) 166*7c478bd9Sstevel@tonic-gate idtype_t idtype; 167*7c478bd9Sstevel@tonic-gate id_t *idptr; 168*7c478bd9Sstevel@tonic-gate { 169*7c478bd9Sstevel@tonic-gate pcinfo_t pcinfo; 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate switch (idtype) { 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate case P_PID: 174*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getpid(); 175*7c478bd9Sstevel@tonic-gate break; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate case P_PPID: 178*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getppid(); 179*7c478bd9Sstevel@tonic-gate break; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate case P_PGID: 182*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getpgrp(); 183*7c478bd9Sstevel@tonic-gate break; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate case P_SID: 186*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getsid(getpid()); 187*7c478bd9Sstevel@tonic-gate break; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate case P_CID: 190*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL, 191*7c478bd9Sstevel@tonic-gate PC_KY_CLNAME, pcinfo.pc_clname, 0) == -1 || 192*7c478bd9Sstevel@tonic-gate priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) 193*7c478bd9Sstevel@tonic-gate return (-1); 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate *idptr = pcinfo.pc_cid; 196*7c478bd9Sstevel@tonic-gate break; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate case P_UID: 199*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getuid(); 200*7c478bd9Sstevel@tonic-gate break; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate case P_GID: 203*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getgid(); 204*7c478bd9Sstevel@tonic-gate break; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate case P_PROJID: 207*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getprojid(); 208*7c478bd9Sstevel@tonic-gate break; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate case P_TASKID: 211*7c478bd9Sstevel@tonic-gate *idptr = (id_t)gettaskid(); 212*7c478bd9Sstevel@tonic-gate break; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate case P_ZONEID: 215*7c478bd9Sstevel@tonic-gate *idptr = (id_t)getzoneid(); 216*7c478bd9Sstevel@tonic-gate break; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate case P_CTID: { 219*7c478bd9Sstevel@tonic-gate ctid_t id = getctid(); 220*7c478bd9Sstevel@tonic-gate if (id == -1) 221*7c478bd9Sstevel@tonic-gate return (-1); 222*7c478bd9Sstevel@tonic-gate *idptr = id; 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate default: 227*7c478bd9Sstevel@tonic-gate return (-1); 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate return (0); 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate int 234*7c478bd9Sstevel@tonic-gate getmyidstr(idtype, idstr) 235*7c478bd9Sstevel@tonic-gate idtype_t idtype; 236*7c478bd9Sstevel@tonic-gate char *idstr; 237*7c478bd9Sstevel@tonic-gate { 238*7c478bd9Sstevel@tonic-gate char clname[PC_CLNMSZ]; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate switch (idtype) { 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate case P_PID: 243*7c478bd9Sstevel@tonic-gate itoa((long)getpid(), idstr); 244*7c478bd9Sstevel@tonic-gate break; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate case P_PPID: 247*7c478bd9Sstevel@tonic-gate itoa((long)getppid(), idstr); 248*7c478bd9Sstevel@tonic-gate break; 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate case P_PGID: 251*7c478bd9Sstevel@tonic-gate itoa((long)getpgrp(), idstr); 252*7c478bd9Sstevel@tonic-gate break; 253*7c478bd9Sstevel@tonic-gate case P_SID: 254*7c478bd9Sstevel@tonic-gate itoa((long)getsid(getpid()), idstr); 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate case P_CID: 258*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL, 259*7c478bd9Sstevel@tonic-gate PC_KY_CLNAME, clname, 0) == -1) 260*7c478bd9Sstevel@tonic-gate return (-1); 261*7c478bd9Sstevel@tonic-gate (void) strncpy(idstr, clname, PC_CLNMSZ); 262*7c478bd9Sstevel@tonic-gate break; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate case P_UID: 265*7c478bd9Sstevel@tonic-gate itoa((long)getuid(), idstr); 266*7c478bd9Sstevel@tonic-gate break; 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate case P_GID: 269*7c478bd9Sstevel@tonic-gate itoa((long)getgid(), idstr); 270*7c478bd9Sstevel@tonic-gate break; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate case P_PROJID: 273*7c478bd9Sstevel@tonic-gate itoa((long)getprojid(), idstr); 274*7c478bd9Sstevel@tonic-gate break; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate case P_TASKID: 277*7c478bd9Sstevel@tonic-gate itoa((long)gettaskid(), idstr); 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate case P_ZONEID: 281*7c478bd9Sstevel@tonic-gate itoa((long)getzoneid(), idstr); 282*7c478bd9Sstevel@tonic-gate break; 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate case P_CTID: { 285*7c478bd9Sstevel@tonic-gate id_t id; 286*7c478bd9Sstevel@tonic-gate if ((id = getctid()) == -1) 287*7c478bd9Sstevel@tonic-gate return (-1); 288*7c478bd9Sstevel@tonic-gate itoa((long)id, idstr); 289*7c478bd9Sstevel@tonic-gate break; 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate default: 293*7c478bd9Sstevel@tonic-gate return (-1); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate return (0); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate /* 299*7c478bd9Sstevel@tonic-gate * Look for pids with "upri > uprilim" in the set specified by idtype/id. 300*7c478bd9Sstevel@tonic-gate * If upri exceeds uprilim then print a warning. 301*7c478bd9Sstevel@tonic-gate */ 302*7c478bd9Sstevel@tonic-gate int 303*7c478bd9Sstevel@tonic-gate verifyupri(idtype_t idtype, id_t id, char *clname, int key, 304*7c478bd9Sstevel@tonic-gate pri_t upri, char *basenm) 305*7c478bd9Sstevel@tonic-gate { 306*7c478bd9Sstevel@tonic-gate psinfo_t prinfo; 307*7c478bd9Sstevel@tonic-gate prcred_t prcred; 308*7c478bd9Sstevel@tonic-gate DIR *dirp; 309*7c478bd9Sstevel@tonic-gate struct dirent *dentp; 310*7c478bd9Sstevel@tonic-gate char pname[MAXNAMLEN]; 311*7c478bd9Sstevel@tonic-gate char *fname; 312*7c478bd9Sstevel@tonic-gate int procfd; 313*7c478bd9Sstevel@tonic-gate int saverr; 314*7c478bd9Sstevel@tonic-gate pri_t uprilim; 315*7c478bd9Sstevel@tonic-gate int verify; 316*7c478bd9Sstevel@tonic-gate int error = 0; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate if (idtype == P_PID) { 319*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, id, PC_GETXPARMS, clname, key, 320*7c478bd9Sstevel@tonic-gate &uprilim, 0) == -1) 321*7c478bd9Sstevel@tonic-gate error = -1; 322*7c478bd9Sstevel@tonic-gate else if (upri > uprilim) 323*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 324*7c478bd9Sstevel@tonic-gate "%s: Specified user priority %d exceeds" 325*7c478bd9Sstevel@tonic-gate " limit %d; set to %d (pid %d)\n", 326*7c478bd9Sstevel@tonic-gate basenm, upri, uprilim, uprilim, (int)id); 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate return (error); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * Look for the processes in the set specified by idtype/id. 333*7c478bd9Sstevel@tonic-gate * We read the /proc/<pid>/psinfo file to get the necessary 334*7c478bd9Sstevel@tonic-gate * process information. 335*7c478bd9Sstevel@tonic-gate */ 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate if ((dirp = opendir(procdir)) == NULL) 338*7c478bd9Sstevel@tonic-gate fatalerr("%s: Can't open PROC directory %s\n", 339*7c478bd9Sstevel@tonic-gate basenm, procdir); 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate while ((dentp = readdir(dirp)) != NULL) { 342*7c478bd9Sstevel@tonic-gate if (dentp->d_name[0] == '.') /* skip . and .. */ 343*7c478bd9Sstevel@tonic-gate continue; 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate (void) snprintf(pname, MAXNAMLEN, "%s/%s/", 346*7c478bd9Sstevel@tonic-gate procdir, dentp->d_name); 347*7c478bd9Sstevel@tonic-gate fname = pname + strlen(pname); 348*7c478bd9Sstevel@tonic-gate retry: 349*7c478bd9Sstevel@tonic-gate (void) strncpy(fname, "psinfo", strlen("psinfo") + 1); 350*7c478bd9Sstevel@tonic-gate if ((procfd = open(pname, O_RDONLY)) < 0) 351*7c478bd9Sstevel@tonic-gate continue; 352*7c478bd9Sstevel@tonic-gate if (read(procfd, &prinfo, sizeof (prinfo)) != sizeof (prinfo)) { 353*7c478bd9Sstevel@tonic-gate saverr = errno; 354*7c478bd9Sstevel@tonic-gate (void) close(procfd); 355*7c478bd9Sstevel@tonic-gate if (saverr == EAGAIN) 356*7c478bd9Sstevel@tonic-gate goto retry; 357*7c478bd9Sstevel@tonic-gate continue; 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate (void) close(procfd); 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate if (idtype == P_UID || idtype == P_GID) { 362*7c478bd9Sstevel@tonic-gate (void) strncpy(fname, "cred", strlen("cred") + 1); 363*7c478bd9Sstevel@tonic-gate if ((procfd = open(pname, O_RDONLY)) < 0 || 364*7c478bd9Sstevel@tonic-gate read(procfd, &prcred, sizeof (prcred)) != 365*7c478bd9Sstevel@tonic-gate sizeof (prcred)) { 366*7c478bd9Sstevel@tonic-gate saverr = errno; 367*7c478bd9Sstevel@tonic-gate (void) close(procfd); 368*7c478bd9Sstevel@tonic-gate if (saverr == EAGAIN) 369*7c478bd9Sstevel@tonic-gate goto retry; 370*7c478bd9Sstevel@tonic-gate continue; 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate (void) close(procfd); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate if (prinfo.pr_lwp.pr_state == 0 || prinfo.pr_nlwp == 0) 376*7c478bd9Sstevel@tonic-gate continue; 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate /* 379*7c478bd9Sstevel@tonic-gate * The lwp must be in the correct class. 380*7c478bd9Sstevel@tonic-gate */ 381*7c478bd9Sstevel@tonic-gate if (strncmp(clname, prinfo.pr_lwp.pr_clname, PC_CLNMSZ) != 0) 382*7c478bd9Sstevel@tonic-gate continue; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate verify = 0; 385*7c478bd9Sstevel@tonic-gate switch (idtype) { 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate case P_PPID: 388*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_ppid) 389*7c478bd9Sstevel@tonic-gate verify++; 390*7c478bd9Sstevel@tonic-gate break; 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate case P_PGID: 393*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_pgid) 394*7c478bd9Sstevel@tonic-gate verify++; 395*7c478bd9Sstevel@tonic-gate break; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate case P_SID: 398*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_sid) 399*7c478bd9Sstevel@tonic-gate verify++; 400*7c478bd9Sstevel@tonic-gate break; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate case P_UID: 403*7c478bd9Sstevel@tonic-gate if (id == (id_t)prcred.pr_euid) 404*7c478bd9Sstevel@tonic-gate verify++; 405*7c478bd9Sstevel@tonic-gate break; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate case P_GID: 408*7c478bd9Sstevel@tonic-gate if (id == (id_t)prcred.pr_egid) 409*7c478bd9Sstevel@tonic-gate verify++; 410*7c478bd9Sstevel@tonic-gate break; 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate case P_PROJID: 413*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_projid) 414*7c478bd9Sstevel@tonic-gate verify++; 415*7c478bd9Sstevel@tonic-gate break; 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate case P_TASKID: 418*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_taskid) 419*7c478bd9Sstevel@tonic-gate verify++; 420*7c478bd9Sstevel@tonic-gate break; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate case P_ZONEID: 423*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_zoneid) 424*7c478bd9Sstevel@tonic-gate verify++; 425*7c478bd9Sstevel@tonic-gate break; 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate case P_CTID: 428*7c478bd9Sstevel@tonic-gate if (id == (id_t)prinfo.pr_contract) 429*7c478bd9Sstevel@tonic-gate verify++; 430*7c478bd9Sstevel@tonic-gate break; 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate case P_CID: 433*7c478bd9Sstevel@tonic-gate case P_ALL: 434*7c478bd9Sstevel@tonic-gate verify++; 435*7c478bd9Sstevel@tonic-gate break; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate default: 438*7c478bd9Sstevel@tonic-gate fatalerr("%s: Bad idtype %d in verifyupri()\n", 439*7c478bd9Sstevel@tonic-gate basenm, idtype); 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if (verify) { 443*7c478bd9Sstevel@tonic-gate if (priocntl(P_PID, prinfo.pr_pid, PC_GETXPARMS, 444*7c478bd9Sstevel@tonic-gate clname, key, &uprilim, 0) == -1) 445*7c478bd9Sstevel@tonic-gate error = -1; 446*7c478bd9Sstevel@tonic-gate else if (upri > uprilim) 447*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 448*7c478bd9Sstevel@tonic-gate "%s: Specified user priority %d exceeds" 449*7c478bd9Sstevel@tonic-gate " limit %d; set to %d (pid %d)\n", 450*7c478bd9Sstevel@tonic-gate basenm, upri, uprilim, uprilim, 451*7c478bd9Sstevel@tonic-gate (int)prinfo.pr_pid); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate (void) closedir(dirp); 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate return (error); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate /* 461*7c478bd9Sstevel@tonic-gate * Read a list of pids from a stream. 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate pid_t * 464*7c478bd9Sstevel@tonic-gate read_pidlist(size_t *npidsp, FILE *filep) 465*7c478bd9Sstevel@tonic-gate { 466*7c478bd9Sstevel@tonic-gate size_t nitems; 467*7c478bd9Sstevel@tonic-gate pid_t *pidlist = NULL; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate *npidsp = 0; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate do { 472*7c478bd9Sstevel@tonic-gate if ((pidlist = (pid_t *)realloc(pidlist, 473*7c478bd9Sstevel@tonic-gate (*npidsp + NPIDS) * sizeof (pid_t))) == NULL) 474*7c478bd9Sstevel@tonic-gate return (NULL); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate nitems = fread(pidlist + *npidsp, sizeof (pid_t), NPIDS, filep); 477*7c478bd9Sstevel@tonic-gate if (ferror(filep)) 478*7c478bd9Sstevel@tonic-gate return (NULL); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate *npidsp += nitems; 481*7c478bd9Sstevel@tonic-gate } while (nitems == NPIDS); 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate return (pidlist); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate void 488*7c478bd9Sstevel@tonic-gate free_pidlist(pid_t *pidlist) 489*7c478bd9Sstevel@tonic-gate { 490*7c478bd9Sstevel@tonic-gate free(pidlist); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate long 495*7c478bd9Sstevel@tonic-gate str2num(char *p, long min, long max) 496*7c478bd9Sstevel@tonic-gate { 497*7c478bd9Sstevel@tonic-gate long val; 498*7c478bd9Sstevel@tonic-gate char *q; 499*7c478bd9Sstevel@tonic-gate errno = 0; 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate val = strtol(p, &q, 10); 502*7c478bd9Sstevel@tonic-gate if (errno != 0 || q == p || *q != '\0' || val < min || val > max) 503*7c478bd9Sstevel@tonic-gate errno = EINVAL; 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate return (val); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate /* 510*7c478bd9Sstevel@tonic-gate * itoa() and reverse() taken almost verbatim from K & R Chapter 3. 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate static void reverse(); 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* 515*7c478bd9Sstevel@tonic-gate * itoa(): Convert n to characters in s. 516*7c478bd9Sstevel@tonic-gate */ 517*7c478bd9Sstevel@tonic-gate void 518*7c478bd9Sstevel@tonic-gate itoa(n, s) 519*7c478bd9Sstevel@tonic-gate long n; 520*7c478bd9Sstevel@tonic-gate char *s; 521*7c478bd9Sstevel@tonic-gate { 522*7c478bd9Sstevel@tonic-gate long i, sign; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate if ((sign = n) < 0) /* record sign */ 525*7c478bd9Sstevel@tonic-gate n = -n; /* make sign positive */ 526*7c478bd9Sstevel@tonic-gate i = 0; 527*7c478bd9Sstevel@tonic-gate do { /* generate digits in reverse order */ 528*7c478bd9Sstevel@tonic-gate s[i++] = n % 10 + '0'; /* get next digit */ 529*7c478bd9Sstevel@tonic-gate } while ((n /= 10) > 0); /* delete it */ 530*7c478bd9Sstevel@tonic-gate if (sign < 0) 531*7c478bd9Sstevel@tonic-gate s[i++] = '-'; 532*7c478bd9Sstevel@tonic-gate s[i] = '\0'; 533*7c478bd9Sstevel@tonic-gate reverse(s); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate /* 538*7c478bd9Sstevel@tonic-gate * reverse(): Reverse string s in place. 539*7c478bd9Sstevel@tonic-gate */ 540*7c478bd9Sstevel@tonic-gate static void 541*7c478bd9Sstevel@tonic-gate reverse(s) 542*7c478bd9Sstevel@tonic-gate char *s; 543*7c478bd9Sstevel@tonic-gate { 544*7c478bd9Sstevel@tonic-gate int c, i, j; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { 547*7c478bd9Sstevel@tonic-gate c = s[i]; 548*7c478bd9Sstevel@tonic-gate s[i] = s[j]; 549*7c478bd9Sstevel@tonic-gate s[j] = (char)c; 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate /* 555*7c478bd9Sstevel@tonic-gate * The following routine was removed from libc (libc/port/gen/hrtnewres.c). 556*7c478bd9Sstevel@tonic-gate * It has also been added to disadmin, so if you fix it here, you should 557*7c478bd9Sstevel@tonic-gate * also probably fix it there. In the long term, this should be recoded to 558*7c478bd9Sstevel@tonic-gate * not be hrt'ish. 559*7c478bd9Sstevel@tonic-gate */ 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate /* 562*7c478bd9Sstevel@tonic-gate * Convert interval expressed in htp->hrt_res to new_res. 563*7c478bd9Sstevel@tonic-gate * 564*7c478bd9Sstevel@tonic-gate * Calculate: (interval * new_res) / htp->hrt_res rounding off as 565*7c478bd9Sstevel@tonic-gate * specified by round. 566*7c478bd9Sstevel@tonic-gate * 567*7c478bd9Sstevel@tonic-gate * Note: All args are assumed to be positive. If 568*7c478bd9Sstevel@tonic-gate * the last divide results in something bigger than 569*7c478bd9Sstevel@tonic-gate * a long, then -1 is returned instead. 570*7c478bd9Sstevel@tonic-gate */ 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate int 573*7c478bd9Sstevel@tonic-gate _hrtnewres(htp, new_res, round) 574*7c478bd9Sstevel@tonic-gate register hrtimer_t *htp; 575*7c478bd9Sstevel@tonic-gate register ulong_t new_res; 576*7c478bd9Sstevel@tonic-gate long round; 577*7c478bd9Sstevel@tonic-gate { 578*7c478bd9Sstevel@tonic-gate register long interval; 579*7c478bd9Sstevel@tonic-gate longlong_t dint; 580*7c478bd9Sstevel@tonic-gate longlong_t dto_res; 581*7c478bd9Sstevel@tonic-gate longlong_t drem; 582*7c478bd9Sstevel@tonic-gate longlong_t dfrom_res; 583*7c478bd9Sstevel@tonic-gate longlong_t prod; 584*7c478bd9Sstevel@tonic-gate longlong_t quot; 585*7c478bd9Sstevel@tonic-gate register long numerator; 586*7c478bd9Sstevel@tonic-gate register long result; 587*7c478bd9Sstevel@tonic-gate ulong_t modulus; 588*7c478bd9Sstevel@tonic-gate ulong_t twomodulus; 589*7c478bd9Sstevel@tonic-gate long temp; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if (new_res > NANOSEC || htp->hrt_rem < 0) 592*7c478bd9Sstevel@tonic-gate return (-1); 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate if (htp->hrt_rem >= htp->hrt_res) { 595*7c478bd9Sstevel@tonic-gate htp->hrt_secs += htp->hrt_rem / htp->hrt_res; 596*7c478bd9Sstevel@tonic-gate htp->hrt_rem = htp->hrt_rem % htp->hrt_res; 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate interval = htp->hrt_rem; 600*7c478bd9Sstevel@tonic-gate if (interval == 0) { 601*7c478bd9Sstevel@tonic-gate htp->hrt_res = new_res; 602*7c478bd9Sstevel@tonic-gate return (0); 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate /* 606*7c478bd9Sstevel@tonic-gate * Try to do the calculations in single precision first 607*7c478bd9Sstevel@tonic-gate * (for speed). If they overflow, use double precision. 608*7c478bd9Sstevel@tonic-gate * What we want to compute is: 609*7c478bd9Sstevel@tonic-gate * 610*7c478bd9Sstevel@tonic-gate * (interval * new_res) / hrt->hrt_res 611*7c478bd9Sstevel@tonic-gate */ 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate numerator = interval * new_res; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate if (numerator / new_res == interval) { 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate /* 618*7c478bd9Sstevel@tonic-gate * The above multiply didn't give overflow since 619*7c478bd9Sstevel@tonic-gate * the division got back the original number. Go 620*7c478bd9Sstevel@tonic-gate * ahead and compute the result. 621*7c478bd9Sstevel@tonic-gate */ 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate result = numerator / htp->hrt_res; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate /* 626*7c478bd9Sstevel@tonic-gate * For HRT_RND, compute the value of: 627*7c478bd9Sstevel@tonic-gate * 628*7c478bd9Sstevel@tonic-gate * (interval * new_res) % htp->hrt_res 629*7c478bd9Sstevel@tonic-gate * 630*7c478bd9Sstevel@tonic-gate * If it is greater than half of the htp->hrt_res, 631*7c478bd9Sstevel@tonic-gate * then rounding increases the result by 1. 632*7c478bd9Sstevel@tonic-gate * 633*7c478bd9Sstevel@tonic-gate * For HRT_RNDUP, we increase the result by 1 if: 634*7c478bd9Sstevel@tonic-gate * 635*7c478bd9Sstevel@tonic-gate * result * htp->hrt_res != numerator 636*7c478bd9Sstevel@tonic-gate * 637*7c478bd9Sstevel@tonic-gate * because this tells us we truncated when calculating 638*7c478bd9Sstevel@tonic-gate * result above. 639*7c478bd9Sstevel@tonic-gate * 640*7c478bd9Sstevel@tonic-gate * We also check for overflow when incrementing result 641*7c478bd9Sstevel@tonic-gate * although this is extremely rare. 642*7c478bd9Sstevel@tonic-gate */ 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate if (round == HRT_RND) { 645*7c478bd9Sstevel@tonic-gate modulus = numerator - result * htp->hrt_res; 646*7c478bd9Sstevel@tonic-gate if ((twomodulus = 2 * modulus) / 2 == modulus) { 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate /* 649*7c478bd9Sstevel@tonic-gate * No overflow (if we overflow in calculation 650*7c478bd9Sstevel@tonic-gate * of twomodulus we fall through and use 651*7c478bd9Sstevel@tonic-gate * double precision). 652*7c478bd9Sstevel@tonic-gate */ 653*7c478bd9Sstevel@tonic-gate if (twomodulus >= htp->hrt_res) { 654*7c478bd9Sstevel@tonic-gate temp = result + 1; 655*7c478bd9Sstevel@tonic-gate if (temp - 1 == result) 656*7c478bd9Sstevel@tonic-gate result++; 657*7c478bd9Sstevel@tonic-gate else 658*7c478bd9Sstevel@tonic-gate return (-1); 659*7c478bd9Sstevel@tonic-gate } 660*7c478bd9Sstevel@tonic-gate htp->hrt_res = new_res; 661*7c478bd9Sstevel@tonic-gate htp->hrt_rem = result; 662*7c478bd9Sstevel@tonic-gate return (0); 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate } else if (round == HRT_RNDUP) { 665*7c478bd9Sstevel@tonic-gate if (result * htp->hrt_res != numerator) { 666*7c478bd9Sstevel@tonic-gate temp = result + 1; 667*7c478bd9Sstevel@tonic-gate if (temp - 1 == result) 668*7c478bd9Sstevel@tonic-gate result++; 669*7c478bd9Sstevel@tonic-gate else 670*7c478bd9Sstevel@tonic-gate return (-1); 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate htp->hrt_res = new_res; 673*7c478bd9Sstevel@tonic-gate htp->hrt_rem = result; 674*7c478bd9Sstevel@tonic-gate return (0); 675*7c478bd9Sstevel@tonic-gate } else { /* round == HRT_TRUNC */ 676*7c478bd9Sstevel@tonic-gate htp->hrt_res = new_res; 677*7c478bd9Sstevel@tonic-gate htp->hrt_rem = result; 678*7c478bd9Sstevel@tonic-gate return (0); 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate /* 683*7c478bd9Sstevel@tonic-gate * We would get overflow doing the calculation is 684*7c478bd9Sstevel@tonic-gate * single precision so do it the slow but careful way. 685*7c478bd9Sstevel@tonic-gate * 686*7c478bd9Sstevel@tonic-gate * Compute the interval times the resolution we are 687*7c478bd9Sstevel@tonic-gate * going to. 688*7c478bd9Sstevel@tonic-gate */ 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate dint = interval; 691*7c478bd9Sstevel@tonic-gate dto_res = new_res; 692*7c478bd9Sstevel@tonic-gate prod = dint * dto_res; 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate /* 695*7c478bd9Sstevel@tonic-gate * For HRT_RND the result will be equal to: 696*7c478bd9Sstevel@tonic-gate * 697*7c478bd9Sstevel@tonic-gate * ((interval * new_res) + htp->hrt_res / 2) / htp->hrt_res 698*7c478bd9Sstevel@tonic-gate * 699*7c478bd9Sstevel@tonic-gate * and for HRT_RNDUP we use: 700*7c478bd9Sstevel@tonic-gate * 701*7c478bd9Sstevel@tonic-gate * ((interval * new_res) + htp->hrt_res - 1) / htp->hrt_res 702*7c478bd9Sstevel@tonic-gate * 703*7c478bd9Sstevel@tonic-gate * This is a different but equivalent way of rounding. 704*7c478bd9Sstevel@tonic-gate */ 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if (round == HRT_RND) { 707*7c478bd9Sstevel@tonic-gate drem = htp->hrt_res / 2; 708*7c478bd9Sstevel@tonic-gate prod = prod + drem; 709*7c478bd9Sstevel@tonic-gate } else if (round == HRT_RNDUP) { 710*7c478bd9Sstevel@tonic-gate drem = htp->hrt_res - 1; 711*7c478bd9Sstevel@tonic-gate prod = prod + drem; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate dfrom_res = htp->hrt_res; 715*7c478bd9Sstevel@tonic-gate quot = prod / dfrom_res; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate /* 718*7c478bd9Sstevel@tonic-gate * If the quotient won't fit in a long, then we have 719*7c478bd9Sstevel@tonic-gate * overflow. Otherwise, return the result. 720*7c478bd9Sstevel@tonic-gate */ 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate if (quot > UINT_MAX) { 723*7c478bd9Sstevel@tonic-gate return (-1); 724*7c478bd9Sstevel@tonic-gate } else { 725*7c478bd9Sstevel@tonic-gate htp->hrt_res = new_res; 726*7c478bd9Sstevel@tonic-gate htp->hrt_rem = (int)quot; 727*7c478bd9Sstevel@tonic-gate return (0); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate } 730