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.2 (Berkeley) 07/20/87 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 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 if (uap->who == 0) 41 uap->who = u.u_procp->p_pgrp; 42 for (p = allproc; p != NULL; p = p->p_nxt) { 43 if (p->p_pgrp == uap->who && 44 p->p_nice < low) 45 low = p->p_nice; 46 } 47 break; 48 49 case PRIO_USER: 50 if (uap->who == 0) 51 uap->who = u.u_uid; 52 for (p = allproc; p != NULL; p = p->p_nxt) { 53 if (p->p_uid == uap->who && 54 p->p_nice < low) 55 low = p->p_nice; 56 } 57 break; 58 59 default: 60 u.u_error = EINVAL; 61 return; 62 } 63 if (low == PRIO_MAX + 1) { 64 u.u_error = ESRCH; 65 return; 66 } 67 u.u_r.r_val1 = low; 68 } 69 70 setpriority() 71 { 72 register struct a { 73 int which; 74 int who; 75 int prio; 76 } *uap = (struct a *)u.u_ap; 77 register struct proc *p; 78 int found = 0; 79 80 switch (uap->which) { 81 82 case PRIO_PROCESS: 83 if (uap->who == 0) 84 p = u.u_procp; 85 else 86 p = pfind(uap->who); 87 if (p == 0) 88 break; 89 donice(p, uap->prio); 90 found++; 91 break; 92 93 case PRIO_PGRP: 94 if (uap->who == 0) 95 uap->who = u.u_procp->p_pgrp; 96 for (p = allproc; p != NULL; p = p->p_nxt) 97 if (p->p_pgrp == uap->who) { 98 donice(p, uap->prio); 99 found++; 100 } 101 break; 102 103 case PRIO_USER: 104 if (uap->who == 0) 105 uap->who = u.u_uid; 106 for (p = allproc; p != NULL; p = p->p_nxt) 107 if (p->p_uid == uap->who) { 108 donice(p, uap->prio); 109 found++; 110 } 111 break; 112 113 default: 114 u.u_error = EINVAL; 115 return; 116 } 117 if (found == 0) 118 u.u_error = ESRCH; 119 } 120 121 donice(p, n) 122 register struct proc *p; 123 register int n; 124 { 125 126 if (u.u_uid && u.u_ruid && 127 u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 128 u.u_error = EPERM; 129 return; 130 } 131 if (n > PRIO_MAX) 132 n = PRIO_MAX; 133 if (n < PRIO_MIN) 134 n = PRIO_MIN; 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 } 142 143 setrlimit() 144 { 145 register struct a { 146 u_int which; 147 struct rlimit *lim; 148 } *uap = (struct a *)u.u_ap; 149 struct rlimit alim; 150 register struct rlimit *alimp; 151 extern unsigned maxdmap; 152 153 if (uap->which >= RLIM_NLIMITS) { 154 u.u_error = EINVAL; 155 return; 156 } 157 alimp = &u.u_rlimit[uap->which]; 158 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 159 sizeof (struct rlimit)); 160 if (u.u_error) 161 return; 162 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 163 if (!suser()) 164 return; 165 switch (uap->which) { 166 167 case RLIMIT_DATA: 168 if (alim.rlim_cur > maxdmap) 169 alim.rlim_cur = maxdmap; 170 if (alim.rlim_max > maxdmap) 171 alim.rlim_max = maxdmap; 172 break; 173 174 case RLIMIT_STACK: 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 *alimp = alim; 182 if (uap->which == RLIMIT_RSS) 183 u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 184 } 185 186 getrlimit() 187 { 188 register struct a { 189 u_int which; 190 struct rlimit *rlp; 191 } *uap = (struct a *)u.u_ap; 192 193 if (uap->which >= RLIM_NLIMITS) { 194 u.u_error = EINVAL; 195 return; 196 } 197 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 198 sizeof (struct rlimit)); 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 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 224 sizeof (struct rusage)); 225 } 226 227 ruadd(ru, ru2) 228 register struct rusage *ru, *ru2; 229 { 230 register long *ip, *ip2; 231 register int i; 232 233 timevaladd(&ru->ru_utime, &ru2->ru_utime); 234 timevaladd(&ru->ru_stime, &ru2->ru_stime); 235 if (ru->ru_maxrss < ru2->ru_maxrss) 236 ru->ru_maxrss = ru2->ru_maxrss; 237 ip = &ru->ru_first; ip2 = &ru2->ru_first; 238 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 239 *ip++ += *ip2++; 240 } 241