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