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