checkpoint
[unix-history] / usr / src / sys / kern / kern_resource.c
CommitLineData
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
18getpriority()
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
74setpriority()
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
129donice(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 151setrlimit()
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 194getrlimit()
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
209getrusage()
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
235ruadd(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}