setgroups check int > NGROUPS, so negative would fail; minor cleanup
[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 *
d9c2f47f 6 * @(#)kern_resource.c 7.9 (Berkeley) %G%
da7c5cc6 7 */
1b64633a 8
94368568 9#include "param.h"
d9c2f47f 10#include "user.h"
94368568 11#include "proc.h"
db1874da 12
93cc02ac
BJ
13/*
14 * Resource controls and accounting.
15 */
16
8eea23a6
KM
17getpriority(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:
d9c2f47f 65 return (EINVAL);
db1874da 66 }
8eea23a6 67 if (low == PRIO_MAX + 1)
d9c2f47f 68 return (ESRCH);
8eea23a6 69 *retval = low;
d9c2f47f 70 return (0);
db1874da
BJ
71}
72
8eea23a6
KM
73/* ARGSUSED */
74setpriority(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:
d9c2f47f 124 return (EINVAL);
db1874da 125 }
3fa5efae 126 if (found == 0)
d9c2f47f
MK
127 return (ESRCH);
128 return (0);
db1874da
BJ
129}
130
8eea23a6
KM
131donice(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 */
151setrlimit(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 164 if (uap->which >= RLIM_NLIMITS)
d9c2f47f 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)))
d9c2f47f 169 return (error);
db1874da 170 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
8eea23a6 171 if (error = suser(u.u_cred, &u.u_acflag))
d9c2f47f 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 191 p->p_maxrss = alim.rlim_cur/NBPG;
d9c2f47f 192 return (0);
db1874da
BJ
193}
194
8eea23a6
KM
195/* ARGSUSED */
196getrlimit(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 205 if (uap->which >= RLIM_NLIMITS)
d9c2f47f
MK
206 return (EINVAL);
207 return (copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
8eea23a6 208 sizeof (struct rlimit)));
db1874da
BJ
209}
210
8eea23a6
KM
211/* ARGSUSED */
212getrusage(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:
d9c2f47f 240 return (EINVAL);
db1874da 241 }
d9c2f47f 242 return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
8eea23a6 243 sizeof (struct rusage)));
db1874da
BJ
244}
245
246ruadd(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}