merge of bill's code plus lint (plus, of course, cleanup of bill's bugs)
[unix-history] / usr / src / sys / kern / kern_resource.c
CommitLineData
88a7a62a 1/* kern_resource.c 4.22 83/05/27 */
1b64633a
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
1b64633a
BJ
5#include "../h/dir.h"
6#include "../h/user.h"
7#include "../h/inode.h"
8#include "../h/proc.h"
9#include "../h/seg.h"
4147b3f6 10#include "../h/fs.h"
9a837405 11#include "../h/uio.h"
db1874da 12#include "../h/vm.h"
04ac1ad8 13#include "../h/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;
26
27 u.u_r.r_val1 = NZERO+20;
28 u.u_error = ESRCH;
29 switch (uap->which) {
30
31 case PRIO_PROCESS:
32 if (uap->who == 0)
33 p = u.u_procp;
34 else
35 p = pfind(uap->who);
36 if (p == 0)
37 return;
19c68d6d 38 u.u_r.r_val1 = p->p_nice;
93cc02ac 39 u.u_error = 0;
db1874da
BJ
40 break;
41
42 case PRIO_PGRP:
43 if (uap->who == 0)
44 uap->who = u.u_procp->p_pgrp;
93cc02ac
BJ
45 for (p = proc; p < procNPROC; p++) {
46 if (p->p_stat == NULL)
47 continue;
db1874da
BJ
48 if (p->p_pgrp == uap->who &&
49 p->p_nice < u.u_r.r_val1) {
50 u.u_r.r_val1 = p->p_nice;
51 u.u_error = 0;
52 }
93cc02ac
BJ
53 }
54 break;
55
56 case PRIO_USER:
57 if (uap->who == 0)
58 uap->who = u.u_uid;
59 for (p = proc; p < procNPROC; p++) {
60 if (p->p_stat == NULL)
61 continue;
62 if (p->p_uid == uap->who &&
63 p->p_nice < u.u_r.r_val1) {
64 u.u_r.r_val1 = p->p_nice;
65 u.u_error = 0;
66 }
67 }
db1874da
BJ
68 break;
69
70 default:
71 u.u_error = EINVAL;
72 break;
73 }
74 u.u_r.r_val1 -= NZERO;
75}
76
77setpriority()
78{
79 register struct a {
80 int which;
81 int who;
82 int prio;
83 } *uap = (struct a *)u.u_ap;
84 register struct proc *p;
85
86 u.u_error = ESRCH;
87 switch (uap->which) {
88
89 case PRIO_PROCESS:
93cc02ac
BJ
90 if (uap->who == 0)
91 p = u.u_procp;
92 else
93 p = pfind(uap->who);
db1874da
BJ
94 if (p == 0)
95 return;
96 donice(p, uap->prio);
97 break;
98
99 case PRIO_PGRP:
93cc02ac
BJ
100 if (uap->who == 0)
101 uap->who = u.u_procp->p_pgrp;
db1874da
BJ
102 for (p = proc; p < procNPROC; p++)
103 if (p->p_pgrp == uap->who)
104 donice(p, uap->prio);
105 break;
106
93cc02ac
BJ
107 case PRIO_USER:
108 if (uap->who == 0)
109 uap->who = u.u_uid;
110 for (p = proc; p < procNPROC; p++)
111 if (p->p_uid == uap->who)
112 donice(p, uap->prio);
113 break;
114
db1874da
BJ
115 default:
116 u.u_error = EINVAL;
117 break;
118 }
119}
120
121donice(p, n)
122 register struct proc *p;
123 register int n;
124{
125
126 if (u.u_uid && u.u_ruid &&
127 u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
93cc02ac 128 u.u_error = EACCES;
db1874da
BJ
129 return;
130 }
93cc02ac 131 n += NZERO;
db1874da
BJ
132 if (n >= 2*NZERO)
133 n = 2*NZERO - 1;
134 if (n < 0)
135 n = 0;
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);
142 if (u.u_error == ESRCH)
143 u.u_error = 0;
144}
145
1edb1cf8 146setrlimit()
db1874da
BJ
147{
148 register struct a {
149 u_int which;
150 struct rlimit *lim;
151 } *uap = (struct a *)u.u_ap;
152 struct rlimit alim;
153 register struct rlimit *alimp;
154
155 if (uap->which >= RLIM_NLIMITS) {
156 u.u_error = EINVAL;
157 return;
158 }
159 alimp = &u.u_rlimit[uap->which];
127f7d76
SL
160 u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
161 sizeof (struct rlimit));
162 if (u.u_error)
db1874da 163 return;
db1874da
BJ
164 if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
165 if (!suser())
166 return;
167 switch (uap->which) {
168
169 case RLIMIT_DATA:
170 if (alim.rlim_cur > ctob(MAXDSIZ))
171 alim.rlim_cur = ctob(MAXDSIZ);
172 break;
173
174 case RLIMIT_STACK:
175 if (alim.rlim_cur > ctob(MAXSSIZ))
176 alim.rlim_cur = ctob(MAXSSIZ);
177 break;
178 }
179 *alimp = alim;
180 if (uap->which == RLIMIT_RSS)
181 u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
182}
183
1edb1cf8 184getrlimit()
db1874da
BJ
185{
186 register struct a {
187 u_int which;
188 struct rlimit *rlp;
189 } *uap = (struct a *)u.u_ap;
190
191 if (uap->which >= RLIM_NLIMITS) {
192 u.u_error = EINVAL;
193 return;
194 }
127f7d76
SL
195 u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
196 sizeof (struct rlimit));
db1874da
BJ
197}
198
199getrusage()
200{
201 register struct a {
202 int who;
203 struct rusage *rusage;
204 } *uap = (struct a *)u.u_ap;
205 register struct rusage *rup;
206
207 switch (uap->who) {
208
209 case RUSAGE_SELF:
210 rup = &u.u_ru;
211 break;
212
213 case RUSAGE_CHILDREN:
214 rup = &u.u_cru;
215 break;
216
217 default:
218 u.u_error = EINVAL;
219 return;
220 }
127f7d76
SL
221 u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
222 sizeof (struct rusage));
db1874da
BJ
223}
224
225ruadd(ru, ru2)
226 register struct rusage *ru, *ru2;
227{
3fd23f5c 228 register long *ip, *ip2;
db1874da
BJ
229 register int i;
230
231 timevaladd(&ru->ru_utime, &ru2->ru_utime);
232 timevaladd(&ru->ru_stime, &ru2->ru_stime);
233 if (ru->ru_maxrss < ru2->ru_maxrss)
234 ru->ru_maxrss = ru2->ru_maxrss;
235 ip = &ru->ru_first; ip2 = &ru2->ru_first;
236 for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
237 *ip++ += *ip2++;
238}