1 /* kern_resource.c 6.1 83/07/29 */ 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 #include "../h/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 27 u.u_r.r_val1 = NZERO+20; 28 u.u_error = ESRCH; 29 switch (uap->which) { 30 31 case PRIO_PROCESS: 32 if (uap->who == 0) 33 p = u.u_procp; 34 else 35 p = pfind(uap->who); 36 if (p == 0) 37 return; 38 u.u_r.r_val1 = p->p_nice; 39 u.u_error = 0; 40 break; 41 42 case PRIO_PGRP: 43 if (uap->who == 0) 44 uap->who = u.u_procp->p_pgrp; 45 for (p = proc; p < procNPROC; p++) { 46 if (p->p_stat == NULL) 47 continue; 48 if (p->p_pgrp == uap->who && 49 p->p_nice < u.u_r.r_val1) { 50 u.u_r.r_val1 = p->p_nice; 51 u.u_error = 0; 52 } 53 } 54 break; 55 56 case PRIO_USER: 57 if (uap->who == 0) 58 uap->who = u.u_uid; 59 for (p = proc; p < procNPROC; p++) { 60 if (p->p_stat == NULL) 61 continue; 62 if (p->p_uid == uap->who && 63 p->p_nice < u.u_r.r_val1) { 64 u.u_r.r_val1 = p->p_nice; 65 u.u_error = 0; 66 } 67 } 68 break; 69 70 default: 71 u.u_error = EINVAL; 72 break; 73 } 74 u.u_r.r_val1 -= NZERO; 75 } 76 77 setpriority() 78 { 79 register struct a { 80 int which; 81 int who; 82 int prio; 83 } *uap = (struct a *)u.u_ap; 84 register struct proc *p; 85 86 u.u_error = ESRCH; 87 switch (uap->which) { 88 89 case PRIO_PROCESS: 90 if (uap->who == 0) 91 p = u.u_procp; 92 else 93 p = pfind(uap->who); 94 if (p == 0) 95 return; 96 donice(p, uap->prio); 97 break; 98 99 case PRIO_PGRP: 100 if (uap->who == 0) 101 uap->who = u.u_procp->p_pgrp; 102 for (p = proc; p < procNPROC; p++) 103 if (p->p_pgrp == uap->who) 104 donice(p, uap->prio); 105 break; 106 107 case PRIO_USER: 108 if (uap->who == 0) 109 uap->who = u.u_uid; 110 for (p = proc; p < procNPROC; p++) 111 if (p->p_uid == uap->who) 112 donice(p, uap->prio); 113 break; 114 115 default: 116 u.u_error = EINVAL; 117 break; 118 } 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 = EACCES; 129 return; 130 } 131 n += NZERO; 132 if (n >= 2*NZERO) 133 n = 2*NZERO - 1; 134 if (n < 0) 135 n = 0; 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 if (u.u_error == ESRCH) 143 u.u_error = 0; 144 } 145 146 setrlimit() 147 { 148 register struct a { 149 u_int which; 150 struct rlimit *lim; 151 } *uap = (struct a *)u.u_ap; 152 struct rlimit alim; 153 register struct rlimit *alimp; 154 155 if (uap->which >= RLIM_NLIMITS) { 156 u.u_error = EINVAL; 157 return; 158 } 159 alimp = &u.u_rlimit[uap->which]; 160 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 161 sizeof (struct rlimit)); 162 if (u.u_error) 163 return; 164 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 165 if (!suser()) 166 return; 167 switch (uap->which) { 168 169 case RLIMIT_DATA: 170 if (alim.rlim_cur > ctob(MAXDSIZ)) 171 alim.rlim_cur = ctob(MAXDSIZ); 172 break; 173 174 case RLIMIT_STACK: 175 if (alim.rlim_cur > ctob(MAXSSIZ)) 176 alim.rlim_cur = ctob(MAXSSIZ); 177 break; 178 } 179 *alimp = alim; 180 if (uap->which == RLIMIT_RSS) 181 u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 182 } 183 184 getrlimit() 185 { 186 register struct a { 187 u_int which; 188 struct rlimit *rlp; 189 } *uap = (struct a *)u.u_ap; 190 191 if (uap->which >= RLIM_NLIMITS) { 192 u.u_error = EINVAL; 193 return; 194 } 195 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 196 sizeof (struct rlimit)); 197 } 198 199 getrusage() 200 { 201 register struct a { 202 int who; 203 struct rusage *rusage; 204 } *uap = (struct a *)u.u_ap; 205 register struct rusage *rup; 206 207 switch (uap->who) { 208 209 case RUSAGE_SELF: 210 rup = &u.u_ru; 211 break; 212 213 case RUSAGE_CHILDREN: 214 rup = &u.u_cru; 215 break; 216 217 default: 218 u.u_error = EINVAL; 219 return; 220 } 221 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 222 sizeof (struct rusage)); 223 } 224 225 ruadd(ru, ru2) 226 register struct rusage *ru, *ru2; 227 { 228 register long *ip, *ip2; 229 register int i; 230 231 timevaladd(&ru->ru_utime, &ru2->ru_utime); 232 timevaladd(&ru->ru_stime, &ru2->ru_stime); 233 if (ru->ru_maxrss < ru2->ru_maxrss) 234 ru->ru_maxrss = ru2->ru_maxrss; 235 ip = &ru->ru_first; ip2 = &ru2->ru_first; 236 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 237 *ip++ += *ip2++; 238 } 239