Files
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

272 lines
5.5 KiB
C
Executable File

/*
* Copyright (c) 1995, by Sun Microsystems, Inc.
* All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* Portions Copyright(c) 1988, Sun Microsystems Inc. */
/* All Rights Reserved */
#pragma ident "@(#)setpriority.c 1.1 95/02/28 SMI" /* SVr4.0 1.1 */
/*LINTLIBRARY*/
#include "synonyms.h"
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/procset.h>
#include <sys/priocntl.h>
#include <sys/tspriocntl.h>
#include <sys/iapriocntl.h>
#include <errno.h>
static int prio_to_idtype(int);
static int init_in_set(idtype_t, id_t);
static int get_clinfo(char *, idtype_t, id_t, pcinfo_t *, pcparms_t *);
int
getpriority(int which, id_t who)
{
id_t id;
idtype_t idtype;
pcinfo_t pcinfo;
pcparms_t pcparms;
int scale, ts_scale, ia_scale; /* amount to scale priority by */
int pri, ts_pri, ia_pri; /* user priority of process */
int ts_found = 0, ia_found = 0; /* process match found? */
if (who == 0)
id = P_MYID;
else
id = who;
idtype = prio_to_idtype(which);
if (idtype == -1) {
errno = EINVAL;
return (-1);
}
if (who < 0) {
errno = ESRCH;
return (-1);
}
/*
* get class ID, name, and attributes for the process(es)
*/
if (get_clinfo("TS", idtype, id, &pcinfo, &pcparms) != -1) {
ts_scale = ((tsinfo_t *)pcinfo.pc_clinfo)->ts_maxupri;
ts_pri = ((tsparms_t *)pcparms.pc_clparms)->ts_upri;
if (ts_pri <= ts_scale && ts_pri >= -ts_scale)
ts_found = 1; /* upri is in valid range */
}
if (get_clinfo("IA", idtype, id, &pcinfo, &pcparms) != -1) {
ia_scale = ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri;
ia_pri = ((iaparms_t *)pcparms.pc_clparms)->ia_upri;
if (ia_pri <= ia_scale && ia_pri >= -ia_scale)
ia_found = 1; /* upri is in valid range */
}
if (!ia_found && !ts_found) {
/*
* Nothing matches in either class.
* errno should have been set by the
* IA call, so we can just return.
*/
return (-1);
} else if (!ia_found) {
/* only in TS */
errno = 0;
scale = ts_scale;
pri = ts_pri;
} else if (!ts_found) {
/* only in IA */
errno = 0;
scale = ia_scale;
pri = ia_pri;
} else {
/* some processes that match in both TS and IA */
if (ts_pri > ia_pri) {
scale = ts_scale;
pri = ts_pri;
} else {
scale = ia_scale;
pri = ia_pri;
}
}
if (scale == 0)
return (0);
else
return (-(pri * 20) / scale);
}
int
setpriority(int which, id_t who, int prio)
{
id_t id;
idtype_t idtype;
pcinfo_t pcinfo;
pcparms_t pcparms;
tsparms_t *tsp;
iaparms_t *iap;
procset_t procset;
id_t ts_cid, ia_cid; /* class IDs */
int ts_scale, ia_scale; /* amount to scale priority by */
int ts_found = 0, ia_found = 0; /* process match found? */
if (who == 0)
id = P_MYID;
else
id = who;
idtype = prio_to_idtype(which);
if (idtype == -1) {
errno = EINVAL;
return (-1);
}
if (who < 0) {
errno = ESRCH;
return(-1);
}
/*
* get class ID, name, and attributes for the process
*/
if (get_clinfo("TS", idtype, id, &pcinfo, &pcparms) != -1) {
ts_scale = ((tsinfo_t *)pcinfo.pc_clinfo)->ts_maxupri;
ts_cid = pcinfo.pc_cid;
ts_found = 1;
}
if (get_clinfo("IA", idtype, id, &pcinfo, &pcparms) != -1) {
ia_scale = ((iainfo_t *)pcinfo.pc_clinfo)->ia_maxupri;
ia_cid = pcinfo.pc_cid;
ia_found = 1;
}
if (!ts_found && !ia_found)
return (-1);
errno = 0; /* clear errno if the IA call failed */
if (prio > 19)
prio = 19;
else if (prio < -20)
prio = -20;
if (ts_found) {
pcparms.pc_cid = ts_cid;
tsp = (tsparms_t *)pcparms.pc_clparms;
tsp->ts_uprilim = tsp->ts_upri = -(ts_scale * prio) / 20;
setprocset(&procset, POP_AND, idtype, id, P_CID, ts_cid);
if (priocntlset(&procset, PC_SETPARMS, (caddr_t)&pcparms) == -1)
return (-1);
if (init_in_set(idtype, id)) {
setprocset(&procset, POP_AND, P_PID, P_INITPID,
P_CID, ts_cid);
if (priocntlset(&procset, PC_SETPARMS,
(caddr_t)&pcparms) == -1)
return (-1);
}
}
if (ia_found) {
pcparms.pc_cid = ia_cid;
iap = (iaparms_t *)pcparms.pc_clparms;
iap->ia_uprilim = iap->ia_upri = -(ia_scale * prio) / 20;
iap->ia_mode = IA_NOCHANGE;
setprocset(&procset, POP_AND, idtype, id, P_CID, ia_cid);
if (priocntlset(&procset, PC_SETPARMS, (caddr_t)&pcparms) == -1)
return (-1);
if (init_in_set(idtype, id)) {
setprocset(&procset, POP_AND, P_PID, P_INITPID,
P_CID, ia_cid);
if (priocntlset(&procset, PC_SETPARMS,
(caddr_t)&pcparms) == -1)
return (-1);
}
}
return(0);
}
static int
prio_to_idtype(int which)
{
switch (which) {
case PRIO_PROCESS:
return (P_PID);
case PRIO_PGRP:
return (P_PGID);
case PRIO_USER:
return (P_UID);
default:
return(-1);
}
}
static int
init_in_set(idtype_t idtype, id_t id)
{
switch (idtype) {
case P_PID:
if (id == P_INITPID)
return (1);
else
return (0);
case P_PGID:
if (id == P_INITPGID)
return (1);
else
return (0);
case P_UID:
if (id == P_INITUID)
return (1);
else
return (0);
default:
return(0);
}
}
static int
get_clinfo(
char *clname,
idtype_t idtype,
id_t id,
pcinfo_t *pcinfo,
pcparms_t *pcparms)
{
(void) strcpy(pcinfo->pc_clname, clname);
if (priocntl(0, 0, PC_GETCID, (caddr_t)pcinfo) == -1)
return (-1);
pcparms->pc_cid = pcinfo->pc_cid;
if (priocntl(idtype, id, PC_GETPARMS, (caddr_t)pcparms) == -1)
return (-1);
return (1);
}