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