reverse sense of pid/pgrp for fcntl, SIOCSPGRP (pgrp is negative)
[unix-history] / usr / src / sys / kern / kern_resource.c
CommitLineData
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
19getpriority()
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
71setpriority()
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
122donice(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 144setrlimit()
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 187getrlimit()
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
202getrusage()
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
228ruadd(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}