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