Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
0880b18e | 2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
da7c5cc6 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
8fe87cbb | 6 | * @(#)kern_resource.c 7.3 (Berkeley) %G% |
da7c5cc6 | 7 | */ |
1b64633a | 8 | |
94368568 | 9 | #include "param.h" |
94368568 JB |
10 | #include "dir.h" |
11 | #include "user.h" | |
94368568 | 12 | #include "proc.h" |
db1874da | 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; | |
8fe87cbb | 25 | register int low = PRIO_MAX + 1; |
db1874da | 26 | |
db1874da BJ |
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) | |
957edfef | 35 | break; |
3fa5efae | 36 | low = p->p_nice; |
db1874da BJ |
37 | break; |
38 | ||
8fe87cbb MT |
39 | case PRIO_PGRP: { |
40 | register struct pgrp *pg; | |
41 | ||
db1874da | 42 | if (uap->who == 0) |
8fe87cbb MT |
43 | pg = u.u_procp->p_pgrp; |
44 | else if ((pg = pgfind(uap->who)) == NULL) | |
45 | break; | |
46 | for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { | |
47 | if (p->p_nice < low) | |
3fa5efae | 48 | low = p->p_nice; |
93cc02ac BJ |
49 | } |
50 | break; | |
8fe87cbb | 51 | } |
93cc02ac BJ |
52 | |
53 | case PRIO_USER: | |
54 | if (uap->who == 0) | |
55 | uap->who = u.u_uid; | |
1d348849 | 56 | for (p = allproc; p != NULL; p = p->p_nxt) { |
93cc02ac | 57 | if (p->p_uid == uap->who && |
3fa5efae MK |
58 | p->p_nice < low) |
59 | low = p->p_nice; | |
93cc02ac | 60 | } |
db1874da BJ |
61 | break; |
62 | ||
63 | default: | |
64 | u.u_error = EINVAL; | |
3fa5efae MK |
65 | return; |
66 | } | |
67 | if (low == PRIO_MAX + 1) { | |
68 | u.u_error = ESRCH; | |
69 | return; | |
db1874da | 70 | } |
3fa5efae | 71 | u.u_r.r_val1 = low; |
db1874da BJ |
72 | } |
73 | ||
74 | setpriority() | |
75 | { | |
76 | register struct a { | |
77 | int which; | |
78 | int who; | |
79 | int prio; | |
80 | } *uap = (struct a *)u.u_ap; | |
81 | register struct proc *p; | |
3fa5efae | 82 | int found = 0; |
db1874da | 83 | |
db1874da BJ |
84 | switch (uap->which) { |
85 | ||
86 | case PRIO_PROCESS: | |
93cc02ac BJ |
87 | if (uap->who == 0) |
88 | p = u.u_procp; | |
89 | else | |
90 | p = pfind(uap->who); | |
db1874da | 91 | if (p == 0) |
957edfef | 92 | break; |
db1874da | 93 | donice(p, uap->prio); |
3fa5efae | 94 | found++; |
db1874da BJ |
95 | break; |
96 | ||
8fe87cbb MT |
97 | case PRIO_PGRP: { |
98 | register struct pgrp *pg; | |
99 | ||
93cc02ac | 100 | if (uap->who == 0) |
8fe87cbb MT |
101 | pg = u.u_procp->p_pgrp; |
102 | else if ((pg = pgfind(uap->who)) == NULL) | |
103 | break; | |
104 | for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { | |
105 | donice(p, uap->prio); | |
106 | found++; | |
107 | } | |
db1874da | 108 | break; |
8fe87cbb | 109 | } |
db1874da | 110 | |
93cc02ac BJ |
111 | case PRIO_USER: |
112 | if (uap->who == 0) | |
113 | uap->who = u.u_uid; | |
1d348849 | 114 | for (p = allproc; p != NULL; p = p->p_nxt) |
3fa5efae | 115 | if (p->p_uid == uap->who) { |
93cc02ac | 116 | donice(p, uap->prio); |
3fa5efae MK |
117 | found++; |
118 | } | |
93cc02ac BJ |
119 | break; |
120 | ||
db1874da BJ |
121 | default: |
122 | u.u_error = EINVAL; | |
3fa5efae | 123 | return; |
db1874da | 124 | } |
3fa5efae MK |
125 | if (found == 0) |
126 | u.u_error = ESRCH; | |
db1874da BJ |
127 | } |
128 | ||
129 | donice(p, n) | |
130 | register struct proc *p; | |
131 | register int n; | |
132 | { | |
133 | ||
134 | if (u.u_uid && u.u_ruid && | |
135 | u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { | |
6e6b3864 | 136 | u.u_error = EPERM; |
db1874da BJ |
137 | return; |
138 | } | |
3fa5efae MK |
139 | if (n > PRIO_MAX) |
140 | n = PRIO_MAX; | |
141 | if (n < PRIO_MIN) | |
142 | n = PRIO_MIN; | |
93cc02ac BJ |
143 | if (n < p->p_nice && !suser()) { |
144 | u.u_error = EACCES; | |
db1874da | 145 | return; |
93cc02ac | 146 | } |
db1874da BJ |
147 | p->p_nice = n; |
148 | (void) setpri(p); | |
db1874da BJ |
149 | } |
150 | ||
1edb1cf8 | 151 | setrlimit() |
db1874da BJ |
152 | { |
153 | register struct a { | |
154 | u_int which; | |
155 | struct rlimit *lim; | |
156 | } *uap = (struct a *)u.u_ap; | |
157 | struct rlimit alim; | |
158 | register struct rlimit *alimp; | |
63ce5236 | 159 | extern unsigned maxdmap; |
db1874da BJ |
160 | |
161 | if (uap->which >= RLIM_NLIMITS) { | |
162 | u.u_error = EINVAL; | |
163 | return; | |
164 | } | |
165 | alimp = &u.u_rlimit[uap->which]; | |
127f7d76 SL |
166 | u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, |
167 | sizeof (struct rlimit)); | |
168 | if (u.u_error) | |
db1874da | 169 | return; |
db1874da BJ |
170 | if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) |
171 | if (!suser()) | |
172 | return; | |
173 | switch (uap->which) { | |
174 | ||
175 | case RLIMIT_DATA: | |
d9937da6 KM |
176 | if (alim.rlim_cur > maxdmap) |
177 | alim.rlim_cur = maxdmap; | |
178 | if (alim.rlim_max > maxdmap) | |
179 | alim.rlim_max = maxdmap; | |
db1874da BJ |
180 | break; |
181 | ||
182 | case RLIMIT_STACK: | |
d9937da6 KM |
183 | if (alim.rlim_cur > maxdmap) |
184 | alim.rlim_cur = maxdmap; | |
185 | if (alim.rlim_max > maxdmap) | |
186 | alim.rlim_max = maxdmap; | |
db1874da BJ |
187 | break; |
188 | } | |
189 | *alimp = alim; | |
190 | if (uap->which == RLIMIT_RSS) | |
191 | u.u_procp->p_maxrss = alim.rlim_cur/NBPG; | |
192 | } | |
193 | ||
1edb1cf8 | 194 | getrlimit() |
db1874da BJ |
195 | { |
196 | register struct a { | |
197 | u_int which; | |
198 | struct rlimit *rlp; | |
199 | } *uap = (struct a *)u.u_ap; | |
200 | ||
201 | if (uap->which >= RLIM_NLIMITS) { | |
202 | u.u_error = EINVAL; | |
203 | return; | |
204 | } | |
127f7d76 SL |
205 | u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, |
206 | sizeof (struct rlimit)); | |
db1874da BJ |
207 | } |
208 | ||
209 | getrusage() | |
210 | { | |
211 | register struct a { | |
212 | int who; | |
213 | struct rusage *rusage; | |
214 | } *uap = (struct a *)u.u_ap; | |
215 | register struct rusage *rup; | |
216 | ||
217 | switch (uap->who) { | |
218 | ||
219 | case RUSAGE_SELF: | |
220 | rup = &u.u_ru; | |
221 | break; | |
222 | ||
223 | case RUSAGE_CHILDREN: | |
224 | rup = &u.u_cru; | |
225 | break; | |
226 | ||
227 | default: | |
228 | u.u_error = EINVAL; | |
229 | return; | |
230 | } | |
127f7d76 SL |
231 | u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, |
232 | sizeof (struct rusage)); | |
db1874da BJ |
233 | } |
234 | ||
235 | ruadd(ru, ru2) | |
236 | register struct rusage *ru, *ru2; | |
237 | { | |
3fd23f5c | 238 | register long *ip, *ip2; |
db1874da BJ |
239 | register int i; |
240 | ||
241 | timevaladd(&ru->ru_utime, &ru2->ru_utime); | |
242 | timevaladd(&ru->ru_stime, &ru2->ru_stime); | |
243 | if (ru->ru_maxrss < ru2->ru_maxrss) | |
244 | ru->ru_maxrss = ru2->ru_maxrss; | |
245 | ip = &ru->ru_first; ip2 = &ru2->ru_first; | |
246 | for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) | |
247 | *ip++ += *ip2++; | |
248 | } |