/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/priocntl.h>
#include <procfs.h>
#include <project.h>
#include <errno.h>
#include <zone.h>
#include <libcontract_priv.h>
#include "priocntl.h"
/*LINTLIBRARY*/
/*
* Utility functions for priocntl command.
*/
/*PRINTFLIKE1*/
void
char *format;
{
exit(1);
}
/*
* Structure defining idtypes known to the priocntl command
* along with the corresponding names
*/
static struct idtypes {
char *idtypnm;
} idtypes [] = {
{ P_PID, "pid" },
{ P_PPID, "ppid" },
{ P_PGID, "pgid" },
{ P_SID, "sid" },
{ P_CID, "class" },
{ P_UID, "uid" },
{ P_GID, "gid" },
{ P_PROJID, "projid" },
{ P_TASKID, "taskid" },
{ P_ZONEID, "zoneid" },
{ P_CTID, "ctid" },
{ P_ALL, "all" }
};
int
char *idtypnm;
{
return (0);
}
}
return (-1);
}
int
char *idtypnm;
{
return (0);
}
}
return (-1);
}
/*
* Compare two IDs for equality.
*/
int
{
return (0);
else
return (-1);
}
char *clname;
{
return ((id_t)-1);
}
int
{
switch (idtype) {
case P_PID:
break;
case P_PPID:
break;
case P_PGID:
break;
case P_SID:
break;
case P_CID:
return (-1);
break;
case P_UID:
break;
case P_GID:
break;
case P_PROJID:
break;
case P_TASKID:
break;
case P_ZONEID:
break;
case P_CTID: {
if (id == -1)
return (-1);
break;
}
default:
return (-1);
}
return (0);
}
int
char *idstr;
{
switch (idtype) {
case P_PID:
break;
case P_PPID:
break;
case P_PGID:
break;
case P_SID:
break;
case P_CID:
return (-1);
break;
case P_UID:
break;
case P_GID:
break;
case P_PROJID:
break;
case P_TASKID:
break;
case P_ZONEID:
break;
case P_CTID: {
return (-1);
break;
}
default:
return (-1);
}
return (0);
}
/*
* If upri exceeds uprilim then print a warning.
*/
int
{
char *fname;
int procfd;
int saverr;
int verify;
int error = 0;
&uprilim, 0) == -1)
error = -1;
"%s: Specified user priority %d exceeds"
" limit %d; set to %d (pid %d)\n",
return (error);
}
/*
* We read the /proc/<pid>/psinfo file to get the necessary
* process information.
*/
fatalerr("%s: Can't open PROC directory %s\n",
continue;
continue;
goto retry;
continue;
}
sizeof (prcred)) {
goto retry;
continue;
}
}
continue;
/*
* The lwp must be in the correct class.
*/
continue;
verify = 0;
switch (idtype) {
case P_PPID:
verify++;
break;
case P_PGID:
verify++;
break;
case P_SID:
verify++;
break;
case P_UID:
verify++;
break;
case P_GID:
verify++;
break;
case P_PROJID:
verify++;
break;
case P_TASKID:
verify++;
break;
case P_ZONEID:
verify++;
break;
case P_CTID:
verify++;
break;
case P_CID:
case P_ALL:
verify++;
break;
default:
fatalerr("%s: Bad idtype %d in verifyupri()\n",
}
if (verify) {
error = -1;
"%s: Specified user priority %d exceeds"
" limit %d; set to %d (pid %d)\n",
}
}
return (error);
}
/*
* Read a list of pids from a stream.
*/
pid_t *
{
*npidsp = 0;
do {
return (NULL);
return (NULL);
return (pidlist);
}
void
{
}
long
{
long val;
char *q;
errno = 0;
return (val);
}
/*
* itoa() and reverse() taken almost verbatim from K & R Chapter 3.
*/
static void reverse();
/*
* itoa(): Convert n to characters in s.
*/
void
itoa(n, s)
long n;
char *s;
{
long i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make sign positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
/*
* reverse(): Reverse string s in place.
*/
static void
reverse(s)
char *s;
{
int c, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = (char)c;
}
}
/*
* The following routine was removed from libc (libc/port/gen/hrtnewres.c).
* It has also been added to disadmin, so if you fix it here, you should
* also probably fix it there. In the long term, this should be recoded to
* not be hrt'ish.
*/
/*
* Convert interval expressed in htp->hrt_res to new_res.
*
* Calculate: (interval * new_res) / htp->hrt_res rounding off as
* specified by round.
*
* Note: All args are assumed to be positive. If
* the last divide results in something bigger than
* a long, then -1 is returned instead.
*/
int
long round;
{
register long interval;
register long numerator;
register long result;
long temp;
return (-1);
}
if (interval == 0) {
return (0);
}
/*
* Try to do the calculations in single precision first
* (for speed). If they overflow, use double precision.
* What we want to compute is:
*
* (interval * new_res) / hrt->hrt_res
*/
/*
* The above multiply didn't give overflow since
* the division got back the original number. Go
* ahead and compute the result.
*/
/*
* For HRT_RND, compute the value of:
*
* (interval * new_res) % htp->hrt_res
*
* If it is greater than half of the htp->hrt_res,
* then rounding increases the result by 1.
*
* For HRT_RNDUP, we increase the result by 1 if:
*
* result * htp->hrt_res != numerator
*
* because this tells us we truncated when calculating
* result above.
*
* We also check for overflow when incrementing result
* although this is extremely rare.
*/
/*
* No overflow (if we overflow in calculation
* of twomodulus we fall through and use
* double precision).
*/
result++;
else
return (-1);
}
return (0);
}
result++;
else
return (-1);
}
return (0);
} else { /* round == HRT_TRUNC */
return (0);
}
}
/*
* We would get overflow doing the calculation is
* single precision so do it the slow but careful way.
*
* Compute the interval times the resolution we are
* going to.
*/
/*
* For HRT_RND the result will be equal to:
*
* ((interval * new_res) + htp->hrt_res / 2) / htp->hrt_res
*
* and for HRT_RNDUP we use:
*
* ((interval * new_res) + htp->hrt_res - 1) / htp->hrt_res
*
* This is a different but equivalent way of rounding.
*/
}
/*
* If the quotient won't fit in a long, then we have
* overflow. Otherwise, return the result.
*/
return (-1);
} else {
return (0);
}
}