1 /* kern_resource.c 4.18 82/12/17 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/inode.h" 8 #include "../h/proc.h" 9 #include "../h/seg.h" 10 #include "../h/fs.h" 11 #include "../h/uio.h" 12 #include "../h/vm.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 26 u.u_r.r_val1 = NZERO+20; 27 u.u_error = ESRCH; 28 switch (uap->which) { 29 30 case PRIO_PROCESS: 31 if (uap->who == 0) 32 p = u.u_procp; 33 else 34 p = pfind(uap->who); 35 if (p == 0) 36 return; 37 u.u_r.r_val1 = u.u_procp->p_nice; 38 u.u_error = 0; 39 break; 40 41 case PRIO_PGRP: 42 if (uap->who == 0) 43 uap->who = u.u_procp->p_pgrp; 44 for (p = proc; p < procNPROC; p++) { 45 if (p->p_stat == NULL) 46 continue; 47 if (p->p_pgrp == uap->who && 48 p->p_nice < u.u_r.r_val1) { 49 u.u_r.r_val1 = p->p_nice; 50 u.u_error = 0; 51 } 52 } 53 break; 54 55 case PRIO_USER: 56 if (uap->who == 0) 57 uap->who = u.u_uid; 58 for (p = proc; p < procNPROC; p++) { 59 if (p->p_stat == NULL) 60 continue; 61 if (p->p_uid == uap->who && 62 p->p_nice < u.u_r.r_val1) { 63 u.u_r.r_val1 = p->p_nice; 64 u.u_error = 0; 65 } 66 } 67 break; 68 69 default: 70 u.u_error = EINVAL; 71 break; 72 } 73 u.u_r.r_val1 -= NZERO; 74 } 75 76 setpriority() 77 { 78 register struct a { 79 int which; 80 int who; 81 int prio; 82 } *uap = (struct a *)u.u_ap; 83 register struct proc *p; 84 85 u.u_error = ESRCH; 86 switch (uap->which) { 87 88 case PRIO_PROCESS: 89 if (uap->who == 0) 90 p = u.u_procp; 91 else 92 p = pfind(uap->who); 93 if (p == 0) 94 return; 95 donice(p, uap->prio); 96 break; 97 98 case PRIO_PGRP: 99 if (uap->who == 0) 100 uap->who = u.u_procp->p_pgrp; 101 for (p = proc; p < procNPROC; p++) 102 if (p->p_pgrp == uap->who) 103 donice(p, uap->prio); 104 break; 105 106 case PRIO_USER: 107 if (uap->who == 0) 108 uap->who = u.u_uid; 109 for (p = proc; p < procNPROC; p++) 110 if (p->p_uid == uap->who) 111 donice(p, uap->prio); 112 break; 113 114 default: 115 u.u_error = EINVAL; 116 break; 117 } 118 } 119 120 donice(p, n) 121 register struct proc *p; 122 register int n; 123 { 124 125 if (u.u_uid && u.u_ruid && 126 u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 127 u.u_error = EACCES; 128 return; 129 } 130 n += NZERO; 131 if (n >= 2*NZERO) 132 n = 2*NZERO - 1; 133 if (n < 0) 134 n = 0; 135 if (n < p->p_nice && !suser()) { 136 u.u_error = EACCES; 137 return; 138 } 139 p->p_nice = n; 140 (void) setpri(p); 141 if (u.u_error == ESRCH) 142 u.u_error = 0; 143 } 144 145 setrlimit() 146 { 147 register struct a { 148 u_int which; 149 struct rlimit *lim; 150 } *uap = (struct a *)u.u_ap; 151 struct rlimit alim; 152 register struct rlimit *alimp; 153 154 if (uap->which >= RLIM_NLIMITS) { 155 u.u_error = EINVAL; 156 return; 157 } 158 alimp = &u.u_rlimit[uap->which]; 159 if (copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) { 160 u.u_error = EFAULT; 161 return; 162 } 163 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 164 if (!suser()) 165 return; 166 switch (uap->which) { 167 168 case RLIMIT_DATA: 169 if (alim.rlim_cur > ctob(MAXDSIZ)) 170 alim.rlim_cur = ctob(MAXDSIZ); 171 break; 172 173 case RLIMIT_STACK: 174 if (alim.rlim_cur > ctob(MAXSSIZ)) 175 alim.rlim_cur = ctob(MAXSSIZ); 176 break; 177 } 178 *alimp = alim; 179 if (uap->which == RLIMIT_RSS) 180 u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 181 } 182 183 getrlimit() 184 { 185 register struct a { 186 u_int which; 187 struct rlimit *rlp; 188 } *uap = (struct a *)u.u_ap; 189 190 if (uap->which >= RLIM_NLIMITS) { 191 u.u_error = EINVAL; 192 return; 193 } 194 if (copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 195 sizeof (struct rlimit))) { 196 u.u_error = EFAULT; 197 return; 198 } 199 } 200 201 getrusage() 202 { 203 register struct a { 204 int who; 205 struct rusage *rusage; 206 } *uap = (struct a *)u.u_ap; 207 register struct rusage *rup; 208 209 switch (uap->who) { 210 211 case RUSAGE_SELF: 212 rup = &u.u_ru; 213 break; 214 215 case RUSAGE_CHILDREN: 216 rup = &u.u_cru; 217 break; 218 219 default: 220 u.u_error = EINVAL; 221 return; 222 } 223 if (copyout((caddr_t)rup, (caddr_t)uap->rusage, 224 sizeof (struct rusage))) { 225 u.u_error = EFAULT; 226 return; 227 } 228 } 229 230 ruadd(ru, ru2) 231 register struct rusage *ru, *ru2; 232 { 233 register long *ip, *ip2; 234 register int i; 235 236 timevaladd(&ru->ru_utime, &ru2->ru_utime); 237 timevaladd(&ru->ru_stime, &ru2->ru_stime); 238 if (ru->ru_maxrss < ru2->ru_maxrss) 239 ru->ru_maxrss = ru2->ru_maxrss; 240 ip = &ru->ru_first; ip2 = &ru2->ru_first; 241 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 242 *ip++ += *ip2++; 243 } 244 245 #ifndef NOCOMPAT 246 onice() 247 { 248 register struct a { 249 int niceness; 250 } *uap = (struct a *)u.u_ap; 251 register struct proc *p = u.u_procp; 252 253 donice(p, (p->p_nice-NZERO)+uap->niceness); 254 } 255 256 #include "../h/times.h" 257 258 otimes() 259 { 260 register struct a { 261 struct tms *tmsb; 262 } *uap = (struct a *)u.u_ap; 263 struct tms atms; 264 265 atms.tms_utime = scale60(&u.u_ru.ru_utime); 266 atms.tms_stime = scale60(&u.u_ru.ru_stime); 267 atms.tms_cutime = scale60(&u.u_cru.ru_utime); 268 atms.tms_cstime = scale60(&u.u_cru.ru_stime); 269 if (copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms))) { 270 u.u_error = EFAULT; 271 return; 272 } 273 } 274 275 scale60(tvp) 276 register struct timeval *tvp; 277 { 278 279 return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); 280 } 281 282 #include "../h/vtimes.h" 283 284 ovtimes() 285 { 286 register struct a { 287 struct vtimes *par; 288 struct vtimes *chi; 289 } *uap = (struct a *)u.u_ap; 290 struct vtimes avt; 291 292 if (uap->par) { 293 getvtimes(&u.u_ru, &avt); 294 if (copyout((caddr_t)&avt, (caddr_t)uap->par, sizeof (avt))) { 295 u.u_error = EFAULT; 296 return; 297 } 298 } 299 if (uap->chi) { 300 getvtimes(&u.u_cru, &avt); 301 if (copyout((caddr_t)&avt, (caddr_t)uap->chi, sizeof (avt))) { 302 u.u_error = EFAULT; 303 return; 304 } 305 } 306 } 307 308 getvtimes(aru, avt) 309 register struct rusage *aru; 310 register struct vtimes *avt; 311 { 312 313 avt->vm_utime = scale60(&aru->ru_utime); 314 avt->vm_stime = scale60(&aru->ru_stime); 315 avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60; 316 avt->vm_ixrss = aru->ru_ixrss / hz * 60; 317 avt->vm_maxrss = aru->ru_maxrss; 318 avt->vm_majflt = aru->ru_majflt; 319 avt->vm_minflt = aru->ru_minflt; 320 avt->vm_nswap = aru->ru_nswap; 321 avt->vm_inblk = aru->ru_inblock; 322 avt->vm_oublk = aru->ru_oublock; 323 } 324 325 ovlimit() 326 { 327 328 u.u_error = EACCES; 329 } 330