1 /* kern_resource.c 4.19 82/12/28 */ 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 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 160 sizeof (struct rlimit)); 161 if (u.u_error) 162 return; 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 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 195 sizeof (struct rlimit)); 196 } 197 198 getrusage() 199 { 200 register struct a { 201 int who; 202 struct rusage *rusage; 203 } *uap = (struct a *)u.u_ap; 204 register struct rusage *rup; 205 206 switch (uap->who) { 207 208 case RUSAGE_SELF: 209 rup = &u.u_ru; 210 break; 211 212 case RUSAGE_CHILDREN: 213 rup = &u.u_cru; 214 break; 215 216 default: 217 u.u_error = EINVAL; 218 return; 219 } 220 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 221 sizeof (struct rusage)); 222 } 223 224 ruadd(ru, ru2) 225 register struct rusage *ru, *ru2; 226 { 227 register long *ip, *ip2; 228 register int i; 229 230 timevaladd(&ru->ru_utime, &ru2->ru_utime); 231 timevaladd(&ru->ru_stime, &ru2->ru_stime); 232 if (ru->ru_maxrss < ru2->ru_maxrss) 233 ru->ru_maxrss = ru2->ru_maxrss; 234 ip = &ru->ru_first; ip2 = &ru2->ru_first; 235 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 236 *ip++ += *ip2++; 237 } 238 239 #ifndef NOCOMPAT 240 onice() 241 { 242 register struct a { 243 int niceness; 244 } *uap = (struct a *)u.u_ap; 245 register struct proc *p = u.u_procp; 246 247 donice(p, (p->p_nice-NZERO)+uap->niceness); 248 } 249 250 #include "../h/times.h" 251 252 otimes() 253 { 254 register struct a { 255 struct tms *tmsb; 256 } *uap = (struct a *)u.u_ap; 257 struct tms atms; 258 259 atms.tms_utime = scale60(&u.u_ru.ru_utime); 260 atms.tms_stime = scale60(&u.u_ru.ru_stime); 261 atms.tms_cutime = scale60(&u.u_cru.ru_utime); 262 atms.tms_cstime = scale60(&u.u_cru.ru_stime); 263 u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms)); 264 } 265 266 scale60(tvp) 267 register struct timeval *tvp; 268 { 269 270 return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); 271 } 272 273 #include "../h/vtimes.h" 274 275 ovtimes() 276 { 277 register struct a { 278 struct vtimes *par; 279 struct vtimes *chi; 280 } *uap = (struct a *)u.u_ap; 281 struct vtimes avt; 282 283 if (uap->par) { 284 getvtimes(&u.u_ru, &avt); 285 u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par, 286 sizeof (avt)); 287 if (u.u_error) 288 return; 289 } 290 if (uap->chi) { 291 getvtimes(&u.u_cru, &avt); 292 u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi, 293 sizeof (avt)); 294 if (u.u_error) 295 return; 296 } 297 } 298 299 getvtimes(aru, avt) 300 register struct rusage *aru; 301 register struct vtimes *avt; 302 { 303 304 avt->vm_utime = scale60(&aru->ru_utime); 305 avt->vm_stime = scale60(&aru->ru_stime); 306 avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60; 307 avt->vm_ixrss = aru->ru_ixrss / hz * 60; 308 avt->vm_maxrss = aru->ru_maxrss; 309 avt->vm_majflt = aru->ru_majflt; 310 avt->vm_minflt = aru->ru_minflt; 311 avt->vm_nswap = aru->ru_nswap; 312 avt->vm_inblk = aru->ru_inblock; 313 avt->vm_oublk = aru->ru_oublock; 314 } 315 316 ovlimit() 317 { 318 319 u.u_error = EACCES; 320 } 321