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