123373Smckusick /* 229093Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323373Smckusick * All rights reserved. The Berkeley software License Agreement 423373Smckusick * specifies the terms and conditions for redistribution. 523373Smckusick * 6*40705Skarels * @(#)kern_resource.c 7.6 (Berkeley) 04/03/90 723373Smckusick */ 87Sbill 917092Sbloom #include "param.h" 1017092Sbloom #include "user.h" 1117092Sbloom #include "proc.h" 127Sbill 138176Sroot /* 148176Sroot * Resource controls and accounting. 158176Sroot */ 168176Sroot 178031Sroot getpriority() 188031Sroot { 198031Sroot register struct a { 208031Sroot int which; 218031Sroot int who; 228031Sroot } *uap = (struct a *)u.u_ap; 238031Sroot register struct proc *p; 2435810Smarc register int low = PRIO_MAX + 1; 258031Sroot 268031Sroot switch (uap->which) { 278031Sroot 288031Sroot case PRIO_PROCESS: 298031Sroot if (uap->who == 0) 308031Sroot p = u.u_procp; 318031Sroot else 328031Sroot p = pfind(uap->who); 338031Sroot if (p == 0) 3428149Skarels break; 3517400Skarels low = p->p_nice; 368031Sroot break; 378031Sroot 3835810Smarc case PRIO_PGRP: { 3935810Smarc register struct pgrp *pg; 4035810Smarc 418031Sroot if (uap->who == 0) 4235810Smarc pg = u.u_procp->p_pgrp; 4335810Smarc else if ((pg = pgfind(uap->who)) == NULL) 4435810Smarc break; 4535810Smarc for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 4635810Smarc if (p->p_nice < low) 4717400Skarels low = p->p_nice; 488176Sroot } 498031Sroot break; 5035810Smarc } 518031Sroot 528176Sroot case PRIO_USER: 538176Sroot if (uap->who == 0) 548176Sroot uap->who = u.u_uid; 5516530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 568176Sroot if (p->p_uid == uap->who && 5717400Skarels p->p_nice < low) 5817400Skarels low = p->p_nice; 598176Sroot } 608176Sroot break; 618176Sroot 628031Sroot default: 638031Sroot u.u_error = EINVAL; 6417400Skarels return; 658031Sroot } 6617400Skarels if (low == PRIO_MAX + 1) { 6717400Skarels u.u_error = ESRCH; 6817400Skarels return; 6917400Skarels } 7017400Skarels u.u_r.r_val1 = low; 718031Sroot } 728031Sroot 738031Sroot setpriority() 748031Sroot { 758031Sroot register struct a { 768031Sroot int which; 778031Sroot int who; 788031Sroot int prio; 798031Sroot } *uap = (struct a *)u.u_ap; 808031Sroot register struct proc *p; 8117400Skarels int found = 0; 828031Sroot 838031Sroot switch (uap->which) { 848031Sroot 858031Sroot case PRIO_PROCESS: 868176Sroot if (uap->who == 0) 878176Sroot p = u.u_procp; 888176Sroot else 898176Sroot p = pfind(uap->who); 908031Sroot if (p == 0) 9128149Skarels break; 928031Sroot donice(p, uap->prio); 9317400Skarels found++; 948031Sroot break; 958031Sroot 9635810Smarc case PRIO_PGRP: { 9735810Smarc register struct pgrp *pg; 9835810Smarc 998176Sroot if (uap->who == 0) 10035810Smarc pg = u.u_procp->p_pgrp; 10135810Smarc else if ((pg = pgfind(uap->who)) == NULL) 10235810Smarc break; 10335810Smarc for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 10435810Smarc donice(p, uap->prio); 10535810Smarc found++; 10635810Smarc } 1078031Sroot break; 10835810Smarc } 1098031Sroot 1108176Sroot case PRIO_USER: 1118176Sroot if (uap->who == 0) 1128176Sroot uap->who = u.u_uid; 11316530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 11417400Skarels if (p->p_uid == uap->who) { 1158176Sroot donice(p, uap->prio); 11617400Skarels found++; 11717400Skarels } 1188176Sroot break; 1198176Sroot 1208031Sroot default: 1218031Sroot u.u_error = EINVAL; 12217400Skarels return; 1238031Sroot } 12417400Skarels if (found == 0) 12517400Skarels u.u_error = ESRCH; 1268031Sroot } 1278031Sroot 1288031Sroot donice(p, n) 1298031Sroot register struct proc *p; 1308031Sroot register int n; 1318031Sroot { 1328031Sroot 1338031Sroot if (u.u_uid && u.u_ruid && 1348031Sroot u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 13521001Smckusick u.u_error = EPERM; 1368031Sroot return; 1378031Sroot } 13817400Skarels if (n > PRIO_MAX) 13917400Skarels n = PRIO_MAX; 14017400Skarels if (n < PRIO_MIN) 14117400Skarels n = PRIO_MIN; 14237553Smckusick if (n < p->p_nice && suser(u.u_cred, &u.u_acflag)) { 1438176Sroot u.u_error = EACCES; 1448031Sroot return; 1458176Sroot } 1468031Sroot p->p_nice = n; 1478031Sroot (void) setpri(p); 1488031Sroot } 1498031Sroot 1508100Sroot setrlimit() 1518031Sroot { 1528031Sroot register struct a { 1538031Sroot u_int which; 1548031Sroot struct rlimit *lim; 1558031Sroot } *uap = (struct a *)u.u_ap; 1568031Sroot struct rlimit alim; 1578031Sroot register struct rlimit *alimp; 15825257Skarels extern unsigned maxdmap; 1598031Sroot 1608031Sroot if (uap->which >= RLIM_NLIMITS) { 1618031Sroot u.u_error = EINVAL; 1628031Sroot return; 1638031Sroot } 1648031Sroot alimp = &u.u_rlimit[uap->which]; 1659997Ssam u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 1669997Ssam sizeof (struct rlimit)); 1679997Ssam if (u.u_error) 1688031Sroot return; 1698031Sroot if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 17037553Smckusick if (u.u_error = suser(u.u_cred, &u.u_acflag)) 1718031Sroot return; 1728031Sroot switch (uap->which) { 1738031Sroot 1748031Sroot case RLIMIT_DATA: 17518279Smckusick if (alim.rlim_cur > maxdmap) 17618279Smckusick alim.rlim_cur = maxdmap; 17718279Smckusick if (alim.rlim_max > maxdmap) 17818279Smckusick alim.rlim_max = maxdmap; 1798031Sroot break; 1808031Sroot 1818031Sroot case RLIMIT_STACK: 18218279Smckusick if (alim.rlim_cur > maxdmap) 18318279Smckusick alim.rlim_cur = maxdmap; 18418279Smckusick if (alim.rlim_max > maxdmap) 18518279Smckusick alim.rlim_max = maxdmap; 1868031Sroot break; 1878031Sroot } 1888031Sroot *alimp = alim; 1898031Sroot if (uap->which == RLIMIT_RSS) 1908031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1918031Sroot } 1928031Sroot 1938100Sroot getrlimit() 1948031Sroot { 1958031Sroot register struct a { 1968031Sroot u_int which; 1978031Sroot struct rlimit *rlp; 1988031Sroot } *uap = (struct a *)u.u_ap; 1998031Sroot 2008031Sroot if (uap->which >= RLIM_NLIMITS) { 2018031Sroot u.u_error = EINVAL; 2028031Sroot return; 2038031Sroot } 2049997Ssam u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 2059997Ssam sizeof (struct rlimit)); 2068031Sroot } 2078031Sroot 2088031Sroot getrusage() 2098031Sroot { 2108031Sroot register struct a { 2118031Sroot int who; 2128031Sroot struct rusage *rusage; 2138031Sroot } *uap = (struct a *)u.u_ap; 2148031Sroot register struct rusage *rup; 215*40705Skarels struct proc *p = u.u_procp; 2168031Sroot 2178031Sroot switch (uap->who) { 2188031Sroot 219*40705Skarels case RUSAGE_SELF: { 220*40705Skarels int s; 221*40705Skarels 2228031Sroot rup = &u.u_ru; 223*40705Skarels s = splclock(); 224*40705Skarels rup->ru_stime = p->p_stime; 225*40705Skarels rup->ru_utime = p->p_utime; 226*40705Skarels splx(s); 2278031Sroot break; 228*40705Skarels } 2298031Sroot 2308031Sroot case RUSAGE_CHILDREN: 2318031Sroot rup = &u.u_cru; 2328031Sroot break; 2338031Sroot 2348031Sroot default: 2358031Sroot u.u_error = EINVAL; 2368031Sroot return; 2378031Sroot } 2389997Ssam u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 2399997Ssam sizeof (struct rusage)); 2408031Sroot } 2418031Sroot 2428031Sroot ruadd(ru, ru2) 2438031Sroot register struct rusage *ru, *ru2; 2448031Sroot { 2458666Sroot register long *ip, *ip2; 2468031Sroot register int i; 2478031Sroot 2488031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2498031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2508031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2518031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2528031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2538031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2548031Sroot *ip++ += *ip2++; 2558031Sroot } 256