1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)kern_resource.c 7.6 (Berkeley) 04/03/90 7 */ 8 9 #include "param.h" 10 #include "user.h" 11 #include "proc.h" 12 13 /* 14 * Resource controls and accounting. 15 */ 16 17 getpriority() 18 { 19 register struct a { 20 int which; 21 int who; 22 } *uap = (struct a *)u.u_ap; 23 register struct proc *p; 24 register int low = PRIO_MAX + 1; 25 26 switch (uap->which) { 27 28 case PRIO_PROCESS: 29 if (uap->who == 0) 30 p = u.u_procp; 31 else 32 p = pfind(uap->who); 33 if (p == 0) 34 break; 35 low = p->p_nice; 36 break; 37 38 case PRIO_PGRP: { 39 register struct pgrp *pg; 40 41 if (uap->who == 0) 42 pg = u.u_procp->p_pgrp; 43 else if ((pg = pgfind(uap->who)) == NULL) 44 break; 45 for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 46 if (p->p_nice < low) 47 low = p->p_nice; 48 } 49 break; 50 } 51 52 case PRIO_USER: 53 if (uap->who == 0) 54 uap->who = u.u_uid; 55 for (p = allproc; p != NULL; p = p->p_nxt) { 56 if (p->p_uid == uap->who && 57 p->p_nice < low) 58 low = p->p_nice; 59 } 60 break; 61 62 default: 63 u.u_error = EINVAL; 64 return; 65 } 66 if (low == PRIO_MAX + 1) { 67 u.u_error = ESRCH; 68 return; 69 } 70 u.u_r.r_val1 = low; 71 } 72 73 setpriority() 74 { 75 register struct a { 76 int which; 77 int who; 78 int prio; 79 } *uap = (struct a *)u.u_ap; 80 register struct proc *p; 81 int found = 0; 82 83 switch (uap->which) { 84 85 case PRIO_PROCESS: 86 if (uap->who == 0) 87 p = u.u_procp; 88 else 89 p = pfind(uap->who); 90 if (p == 0) 91 break; 92 donice(p, uap->prio); 93 found++; 94 break; 95 96 case PRIO_PGRP: { 97 register struct pgrp *pg; 98 99 if (uap->who == 0) 100 pg = u.u_procp->p_pgrp; 101 else if ((pg = pgfind(uap->who)) == NULL) 102 break; 103 for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 104 donice(p, uap->prio); 105 found++; 106 } 107 break; 108 } 109 110 case PRIO_USER: 111 if (uap->who == 0) 112 uap->who = u.u_uid; 113 for (p = allproc; p != NULL; p = p->p_nxt) 114 if (p->p_uid == uap->who) { 115 donice(p, uap->prio); 116 found++; 117 } 118 break; 119 120 default: 121 u.u_error = EINVAL; 122 return; 123 } 124 if (found == 0) 125 u.u_error = ESRCH; 126 } 127 128 donice(p, n) 129 register struct proc *p; 130 register int n; 131 { 132 133 if (u.u_uid && u.u_ruid && 134 u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 135 u.u_error = EPERM; 136 return; 137 } 138 if (n > PRIO_MAX) 139 n = PRIO_MAX; 140 if (n < PRIO_MIN) 141 n = PRIO_MIN; 142 if (n < p->p_nice && suser(u.u_cred, &u.u_acflag)) { 143 u.u_error = EACCES; 144 return; 145 } 146 p->p_nice = n; 147 (void) setpri(p); 148 } 149 150 setrlimit() 151 { 152 register struct a { 153 u_int which; 154 struct rlimit *lim; 155 } *uap = (struct a *)u.u_ap; 156 struct rlimit alim; 157 register struct rlimit *alimp; 158 extern unsigned maxdmap; 159 160 if (uap->which >= RLIM_NLIMITS) { 161 u.u_error = EINVAL; 162 return; 163 } 164 alimp = &u.u_rlimit[uap->which]; 165 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 166 sizeof (struct rlimit)); 167 if (u.u_error) 168 return; 169 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 170 if (u.u_error = suser(u.u_cred, &u.u_acflag)) 171 return; 172 switch (uap->which) { 173 174 case RLIMIT_DATA: 175 if (alim.rlim_cur > maxdmap) 176 alim.rlim_cur = maxdmap; 177 if (alim.rlim_max > maxdmap) 178 alim.rlim_max = maxdmap; 179 break; 180 181 case RLIMIT_STACK: 182 if (alim.rlim_cur > maxdmap) 183 alim.rlim_cur = maxdmap; 184 if (alim.rlim_max > maxdmap) 185 alim.rlim_max = maxdmap; 186 break; 187 } 188 *alimp = alim; 189 if (uap->which == RLIMIT_RSS) 190 u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 191 } 192 193 getrlimit() 194 { 195 register struct a { 196 u_int which; 197 struct rlimit *rlp; 198 } *uap = (struct a *)u.u_ap; 199 200 if (uap->which >= RLIM_NLIMITS) { 201 u.u_error = EINVAL; 202 return; 203 } 204 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 205 sizeof (struct rlimit)); 206 } 207 208 getrusage() 209 { 210 register struct a { 211 int who; 212 struct rusage *rusage; 213 } *uap = (struct a *)u.u_ap; 214 register struct rusage *rup; 215 struct proc *p = u.u_procp; 216 217 switch (uap->who) { 218 219 case RUSAGE_SELF: { 220 int s; 221 222 rup = &u.u_ru; 223 s = splclock(); 224 rup->ru_stime = p->p_stime; 225 rup->ru_utime = p->p_utime; 226 splx(s); 227 break; 228 } 229 230 case RUSAGE_CHILDREN: 231 rup = &u.u_cru; 232 break; 233 234 default: 235 u.u_error = EINVAL; 236 return; 237 } 238 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 239 sizeof (struct rusage)); 240 } 241 242 ruadd(ru, ru2) 243 register struct rusage *ru, *ru2; 244 { 245 register long *ip, *ip2; 246 register int i; 247 248 timevaladd(&ru->ru_utime, &ru2->ru_utime); 249 timevaladd(&ru->ru_stime, &ru2->ru_stime); 250 if (ru->ru_maxrss < ru2->ru_maxrss) 251 ru->ru_maxrss = ru2->ru_maxrss; 252 ip = &ru->ru_first; ip2 = &ru2->ru_first; 253 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 254 *ip++ += *ip2++; 255 } 256