Commit | Line | Data |
---|---|---|
961945a8 | 1 | /* kern_resource.c 4.18 82/12/17 */ |
1b64633a BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
1b64633a BJ |
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" | |
4147b3f6 | 10 | #include "../h/fs.h" |
9a837405 | 11 | #include "../h/uio.h" |
db1874da BJ |
12 | #include "../h/vm.h" |
13 | ||
93cc02ac BJ |
14 | /* |
15 | * Resource controls and accounting. | |
16 | */ | |
17 | ||
db1874da BJ |
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; | |
93cc02ac | 38 | u.u_error = 0; |
db1874da BJ |
39 | break; |
40 | ||
41 | case PRIO_PGRP: | |
42 | if (uap->who == 0) | |
43 | uap->who = u.u_procp->p_pgrp; | |
93cc02ac BJ |
44 | for (p = proc; p < procNPROC; p++) { |
45 | if (p->p_stat == NULL) | |
46 | continue; | |
db1874da BJ |
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 | } | |
93cc02ac BJ |
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 | } | |
db1874da BJ |
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: | |
93cc02ac BJ |
89 | if (uap->who == 0) |
90 | p = u.u_procp; | |
91 | else | |
92 | p = pfind(uap->who); | |
db1874da BJ |
93 | if (p == 0) |
94 | return; | |
95 | donice(p, uap->prio); | |
96 | break; | |
97 | ||
98 | case PRIO_PGRP: | |
93cc02ac BJ |
99 | if (uap->who == 0) |
100 | uap->who = u.u_procp->p_pgrp; | |
db1874da BJ |
101 | for (p = proc; p < procNPROC; p++) |
102 | if (p->p_pgrp == uap->who) | |
103 | donice(p, uap->prio); | |
104 | break; | |
105 | ||
93cc02ac BJ |
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 | ||
db1874da BJ |
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) { | |
93cc02ac | 127 | u.u_error = EACCES; |
db1874da BJ |
128 | return; |
129 | } | |
93cc02ac | 130 | n += NZERO; |
db1874da BJ |
131 | if (n >= 2*NZERO) |
132 | n = 2*NZERO - 1; | |
133 | if (n < 0) | |
134 | n = 0; | |
93cc02ac BJ |
135 | if (n < p->p_nice && !suser()) { |
136 | u.u_error = EACCES; | |
db1874da | 137 | return; |
93cc02ac | 138 | } |
db1874da BJ |
139 | p->p_nice = n; |
140 | (void) setpri(p); | |
141 | if (u.u_error == ESRCH) | |
142 | u.u_error = 0; | |
143 | } | |
144 | ||
1edb1cf8 | 145 | setrlimit() |
db1874da BJ |
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 | ||
1edb1cf8 | 183 | getrlimit() |
db1874da BJ |
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 | } | |
b32450f4 | 194 | if (copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, |
db1874da BJ |
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 | } | |
b32450f4 BJ |
223 | if (copyout((caddr_t)rup, (caddr_t)uap->rusage, |
224 | sizeof (struct rusage))) { | |
db1874da BJ |
225 | u.u_error = EFAULT; |
226 | return; | |
227 | } | |
228 | } | |
229 | ||
230 | ruadd(ru, ru2) | |
231 | register struct rusage *ru, *ru2; | |
232 | { | |
3fd23f5c | 233 | register long *ip, *ip2; |
db1874da BJ |
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 | } | |
1b64633a | 244 | |
1edb1cf8 BJ |
245 | #ifndef NOCOMPAT |
246 | onice() | |
1b64633a | 247 | { |
1b64633a | 248 | register struct a { |
1edb1cf8 | 249 | int niceness; |
93cc02ac BJ |
250 | } *uap = (struct a *)u.u_ap; |
251 | register struct proc *p = u.u_procp; | |
1b64633a | 252 | |
93cc02ac | 253 | donice(p, (p->p_nice-NZERO)+uap->niceness); |
1b64633a | 254 | } |
93cc02ac BJ |
255 | |
256 | #include "../h/times.h" | |
1b64633a | 257 | |
1edb1cf8 | 258 | otimes() |
93cc02ac BJ |
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); | |
b32450f4 | 269 | if (copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms))) { |
93cc02ac BJ |
270 | u.u_error = EFAULT; |
271 | return; | |
272 | } | |
273 | } | |
274 | ||
275 | scale60(tvp) | |
276 | register struct timeval *tvp; | |
1b64633a | 277 | { |
1edb1cf8 | 278 | |
93cc02ac | 279 | return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); |
1b64633a BJ |
280 | } |
281 | ||
961945a8 | 282 | #include "../h/vtimes.h" |
93cc02ac | 283 | |
1edb1cf8 | 284 | ovtimes() |
93cc02ac BJ |
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; | |
1b64633a | 311 | { |
1b64633a | 312 | |
93cc02ac BJ |
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; | |
1b64633a | 323 | } |
4147b3f6 | 324 | |
1edb1cf8 | 325 | ovlimit() |
4147b3f6 | 326 | { |
4147b3f6 | 327 | |
93cc02ac | 328 | u.u_error = EACCES; |
4147b3f6 | 329 | } |