Commit | Line | Data |
---|---|---|
127f7d76 | 1 | /* kern_resource.c 4.19 82/12/28 */ |
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]; | |
127f7d76 SL |
159 | u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, |
160 | sizeof (struct rlimit)); | |
161 | if (u.u_error) | |
db1874da | 162 | return; |
db1874da BJ |
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 | } | |
127f7d76 SL |
194 | u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, |
195 | sizeof (struct rlimit)); | |
db1874da BJ |
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 | } | |
127f7d76 SL |
220 | u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, |
221 | sizeof (struct rusage)); | |
db1874da BJ |
222 | } |
223 | ||
224 | ruadd(ru, ru2) | |
225 | register struct rusage *ru, *ru2; | |
226 | { | |
3fd23f5c | 227 | register long *ip, *ip2; |
db1874da BJ |
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 | } | |
1b64633a | 238 | |
1edb1cf8 BJ |
239 | #ifndef NOCOMPAT |
240 | onice() | |
1b64633a | 241 | { |
1b64633a | 242 | register struct a { |
1edb1cf8 | 243 | int niceness; |
93cc02ac BJ |
244 | } *uap = (struct a *)u.u_ap; |
245 | register struct proc *p = u.u_procp; | |
1b64633a | 246 | |
93cc02ac | 247 | donice(p, (p->p_nice-NZERO)+uap->niceness); |
1b64633a | 248 | } |
93cc02ac BJ |
249 | |
250 | #include "../h/times.h" | |
1b64633a | 251 | |
1edb1cf8 | 252 | otimes() |
93cc02ac BJ |
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); | |
127f7d76 | 263 | u.u_error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms)); |
93cc02ac BJ |
264 | } |
265 | ||
266 | scale60(tvp) | |
267 | register struct timeval *tvp; | |
1b64633a | 268 | { |
1edb1cf8 | 269 | |
93cc02ac | 270 | return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); |
1b64633a BJ |
271 | } |
272 | ||
961945a8 | 273 | #include "../h/vtimes.h" |
93cc02ac | 274 | |
1edb1cf8 | 275 | ovtimes() |
93cc02ac BJ |
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); | |
127f7d76 SL |
285 | u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->par, |
286 | sizeof (avt)); | |
287 | if (u.u_error) | |
93cc02ac | 288 | return; |
93cc02ac BJ |
289 | } |
290 | if (uap->chi) { | |
291 | getvtimes(&u.u_cru, &avt); | |
127f7d76 SL |
292 | u.u_error = copyout((caddr_t)&avt, (caddr_t)uap->chi, |
293 | sizeof (avt)); | |
294 | if (u.u_error) | |
93cc02ac | 295 | return; |
93cc02ac BJ |
296 | } |
297 | } | |
298 | ||
299 | getvtimes(aru, avt) | |
300 | register struct rusage *aru; | |
301 | register struct vtimes *avt; | |
1b64633a | 302 | { |
1b64633a | 303 | |
93cc02ac BJ |
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; | |
1b64633a | 314 | } |
4147b3f6 | 315 | |
1edb1cf8 | 316 | ovlimit() |
4147b3f6 | 317 | { |
4147b3f6 | 318 | |
93cc02ac | 319 | u.u_error = EACCES; |
4147b3f6 | 320 | } |