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 | * | |
5d9a3141 | 6 | * @(#)kern_resource.c 7.2 (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; | |
3fa5efae | 25 | 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 | ||
39 | case PRIO_PGRP: | |
40 | if (uap->who == 0) | |
41 | uap->who = u.u_procp->p_pgrp; | |
1d348849 | 42 | for (p = allproc; p != NULL; p = p->p_nxt) { |
db1874da | 43 | if (p->p_pgrp == uap->who && |
3fa5efae MK |
44 | p->p_nice < low) |
45 | low = p->p_nice; | |
93cc02ac BJ |
46 | } |
47 | break; | |
48 | ||
49 | case PRIO_USER: | |
50 | if (uap->who == 0) | |
51 | uap->who = u.u_uid; | |
1d348849 | 52 | for (p = allproc; p != NULL; p = p->p_nxt) { |
93cc02ac | 53 | if (p->p_uid == uap->who && |
3fa5efae MK |
54 | p->p_nice < low) |
55 | low = p->p_nice; | |
93cc02ac | 56 | } |
db1874da BJ |
57 | break; |
58 | ||
59 | default: | |
60 | u.u_error = EINVAL; | |
3fa5efae MK |
61 | return; |
62 | } | |
63 | if (low == PRIO_MAX + 1) { | |
64 | u.u_error = ESRCH; | |
65 | return; | |
db1874da | 66 | } |
3fa5efae | 67 | u.u_r.r_val1 = low; |
db1874da BJ |
68 | } |
69 | ||
70 | setpriority() | |
71 | { | |
72 | register struct a { | |
73 | int which; | |
74 | int who; | |
75 | int prio; | |
76 | } *uap = (struct a *)u.u_ap; | |
77 | register struct proc *p; | |
3fa5efae | 78 | int found = 0; |
db1874da | 79 | |
db1874da BJ |
80 | switch (uap->which) { |
81 | ||
82 | case PRIO_PROCESS: | |
93cc02ac BJ |
83 | if (uap->who == 0) |
84 | p = u.u_procp; | |
85 | else | |
86 | p = pfind(uap->who); | |
db1874da | 87 | if (p == 0) |
957edfef | 88 | break; |
db1874da | 89 | donice(p, uap->prio); |
3fa5efae | 90 | found++; |
db1874da BJ |
91 | break; |
92 | ||
93 | case PRIO_PGRP: | |
93cc02ac BJ |
94 | if (uap->who == 0) |
95 | uap->who = u.u_procp->p_pgrp; | |
1d348849 | 96 | for (p = allproc; p != NULL; p = p->p_nxt) |
3fa5efae | 97 | if (p->p_pgrp == uap->who) { |
db1874da | 98 | donice(p, uap->prio); |
3fa5efae MK |
99 | found++; |
100 | } | |
db1874da BJ |
101 | break; |
102 | ||
93cc02ac BJ |
103 | case PRIO_USER: |
104 | if (uap->who == 0) | |
105 | uap->who = u.u_uid; | |
1d348849 | 106 | for (p = allproc; p != NULL; p = p->p_nxt) |
3fa5efae | 107 | if (p->p_uid == uap->who) { |
93cc02ac | 108 | donice(p, uap->prio); |
3fa5efae MK |
109 | found++; |
110 | } | |
93cc02ac BJ |
111 | break; |
112 | ||
db1874da BJ |
113 | default: |
114 | u.u_error = EINVAL; | |
3fa5efae | 115 | return; |
db1874da | 116 | } |
3fa5efae MK |
117 | if (found == 0) |
118 | u.u_error = ESRCH; | |
db1874da BJ |
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) { | |
6e6b3864 | 128 | u.u_error = EPERM; |
db1874da BJ |
129 | return; |
130 | } | |
3fa5efae MK |
131 | if (n > PRIO_MAX) |
132 | n = PRIO_MAX; | |
133 | if (n < PRIO_MIN) | |
134 | n = PRIO_MIN; | |
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); | |
db1874da BJ |
141 | } |
142 | ||
1edb1cf8 | 143 | setrlimit() |
db1874da BJ |
144 | { |
145 | register struct a { | |
146 | u_int which; | |
147 | struct rlimit *lim; | |
148 | } *uap = (struct a *)u.u_ap; | |
149 | struct rlimit alim; | |
150 | register struct rlimit *alimp; | |
63ce5236 | 151 | extern unsigned maxdmap; |
db1874da BJ |
152 | |
153 | if (uap->which >= RLIM_NLIMITS) { | |
154 | u.u_error = EINVAL; | |
155 | return; | |
156 | } | |
157 | alimp = &u.u_rlimit[uap->which]; | |
127f7d76 SL |
158 | u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, |
159 | sizeof (struct rlimit)); | |
160 | if (u.u_error) | |
db1874da | 161 | return; |
db1874da BJ |
162 | if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) |
163 | if (!suser()) | |
164 | return; | |
165 | switch (uap->which) { | |
166 | ||
167 | case RLIMIT_DATA: | |
d9937da6 KM |
168 | if (alim.rlim_cur > maxdmap) |
169 | alim.rlim_cur = maxdmap; | |
170 | if (alim.rlim_max > maxdmap) | |
171 | alim.rlim_max = maxdmap; | |
db1874da BJ |
172 | break; |
173 | ||
174 | case RLIMIT_STACK: | |
d9937da6 KM |
175 | if (alim.rlim_cur > maxdmap) |
176 | alim.rlim_cur = maxdmap; | |
177 | if (alim.rlim_max > maxdmap) | |
178 | alim.rlim_max = maxdmap; | |
db1874da BJ |
179 | break; |
180 | } | |
181 | *alimp = alim; | |
182 | if (uap->which == RLIMIT_RSS) | |
183 | u.u_procp->p_maxrss = alim.rlim_cur/NBPG; | |
184 | } | |
185 | ||
1edb1cf8 | 186 | getrlimit() |
db1874da BJ |
187 | { |
188 | register struct a { | |
189 | u_int which; | |
190 | struct rlimit *rlp; | |
191 | } *uap = (struct a *)u.u_ap; | |
192 | ||
193 | if (uap->which >= RLIM_NLIMITS) { | |
194 | u.u_error = EINVAL; | |
195 | return; | |
196 | } | |
127f7d76 SL |
197 | u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, |
198 | sizeof (struct rlimit)); | |
db1874da BJ |
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 | } | |
127f7d76 SL |
223 | u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, |
224 | sizeof (struct rusage)); | |
db1874da BJ |
225 | } |
226 | ||
227 | ruadd(ru, ru2) | |
228 | register struct rusage *ru, *ru2; | |
229 | { | |
3fd23f5c | 230 | register long *ip, *ip2; |
db1874da BJ |
231 | register int i; |
232 | ||
233 | timevaladd(&ru->ru_utime, &ru2->ru_utime); | |
234 | timevaladd(&ru->ru_stime, &ru2->ru_stime); | |
235 | if (ru->ru_maxrss < ru2->ru_maxrss) | |
236 | ru->ru_maxrss = ru2->ru_maxrss; | |
237 | ip = &ru->ru_first; ip2 = &ru2->ru_first; | |
238 | for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) | |
239 | *ip++ += *ip2++; | |
240 | } |