xref: /original-bsd/sys/kern/kern_resource.c (revision f0fd5f8a)
1 /*	kern_resource.c	4.18	82/12/17	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
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"
10 #include "../h/fs.h"
11 #include "../h/uio.h"
12 #include "../h/vm.h"
13 
14 /*
15  * Resource controls and accounting.
16  */
17 
18 getpriority()
19 {
20 	register struct a {
21 		int	which;
22 		int	who;
23 	} *uap = (struct a *)u.u_ap;
24 	register struct proc *p;
25 
26 	u.u_r.r_val1 = NZERO+20;
27 	u.u_error = ESRCH;
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;
37 		u.u_r.r_val1 = u.u_procp->p_nice;
38 		u.u_error = 0;
39 		break;
40 
41 	case PRIO_PGRP:
42 		if (uap->who == 0)
43 			uap->who = u.u_procp->p_pgrp;
44 		for (p = proc; p < procNPROC; p++) {
45 			if (p->p_stat == NULL)
46 				continue;
47 			if (p->p_pgrp == uap->who &&
48 			    p->p_nice < u.u_r.r_val1) {
49 				u.u_r.r_val1 = p->p_nice;
50 				u.u_error = 0;
51 			}
52 		}
53 		break;
54 
55 	case PRIO_USER:
56 		if (uap->who == 0)
57 			uap->who = u.u_uid;
58 		for (p = proc; p < procNPROC; p++) {
59 			if (p->p_stat == NULL)
60 				continue;
61 			if (p->p_uid == uap->who &&
62 			    p->p_nice < u.u_r.r_val1) {
63 				u.u_r.r_val1 = p->p_nice;
64 				u.u_error = 0;
65 			}
66 		}
67 		break;
68 
69 	default:
70 		u.u_error = EINVAL;
71 		break;
72 	}
73 	u.u_r.r_val1 -= NZERO;
74 }
75 
76 setpriority()
77 {
78 	register struct a {
79 		int	which;
80 		int	who;
81 		int	prio;
82 	} *uap = (struct a *)u.u_ap;
83 	register struct proc *p;
84 
85 	u.u_error = ESRCH;
86 	switch (uap->which) {
87 
88 	case PRIO_PROCESS:
89 		if (uap->who == 0)
90 			p = u.u_procp;
91 		else
92 			p = pfind(uap->who);
93 		if (p == 0)
94 			return;
95 		donice(p, uap->prio);
96 		break;
97 
98 	case PRIO_PGRP:
99 		if (uap->who == 0)
100 			uap->who = u.u_procp->p_pgrp;
101 		for (p = proc; p < procNPROC; p++)
102 			if (p->p_pgrp == uap->who)
103 				donice(p, uap->prio);
104 		break;
105 
106 	case PRIO_USER:
107 		if (uap->who == 0)
108 			uap->who = u.u_uid;
109 		for (p = proc; p < procNPROC; p++)
110 			if (p->p_uid == uap->who)
111 				donice(p, uap->prio);
112 		break;
113 
114 	default:
115 		u.u_error = EINVAL;
116 		break;
117 	}
118 }
119 
120 donice(p, n)
121 	register struct proc *p;
122 	register int n;
123 {
124 
125 	if (u.u_uid && u.u_ruid &&
126 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
127 		u.u_error = EACCES;
128 		return;
129 	}
130 	n += NZERO;
131 	if (n >= 2*NZERO)
132 		n = 2*NZERO - 1;
133 	if (n < 0)
134 		n = 0;
135 	if (n < p->p_nice && !suser()) {
136 		u.u_error = EACCES;
137 		return;
138 	}
139 	p->p_nice = n;
140 	(void) setpri(p);
141 	if (u.u_error == ESRCH)
142 		u.u_error = 0;
143 }
144 
145 setrlimit()
146 {
147 	register struct a {
148 		u_int	which;
149 		struct	rlimit *lim;
150 	} *uap = (struct a *)u.u_ap;
151 	struct rlimit alim;
152 	register struct rlimit *alimp;
153 
154 	if (uap->which >= RLIM_NLIMITS) {
155 		u.u_error = EINVAL;
156 		return;
157 	}
158 	alimp = &u.u_rlimit[uap->which];
159 	if (copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) {
160 		u.u_error = EFAULT;
161 		return;
162 	}
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:
169 		if (alim.rlim_cur > ctob(MAXDSIZ))
170 			alim.rlim_cur = ctob(MAXDSIZ);
171 		break;
172 
173 	case RLIMIT_STACK:
174 		if (alim.rlim_cur > ctob(MAXSSIZ))
175 			alim.rlim_cur = ctob(MAXSSIZ);
176 		break;
177 	}
178 	*alimp = alim;
179 	if (uap->which == RLIMIT_RSS)
180 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
181 }
182 
183 getrlimit()
184 {
185 	register struct a {
186 		u_int	which;
187 		struct	rlimit *rlp;
188 	} *uap = (struct a *)u.u_ap;
189 
190 	if (uap->which >= RLIM_NLIMITS) {
191 		u.u_error = EINVAL;
192 		return;
193 	}
194 	if (copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
195 	    sizeof (struct rlimit))) {
196 		u.u_error = EFAULT;
197 		return;
198 	}
199 }
200 
201 getrusage()
202 {
203 	register struct a {
204 		int	who;
205 		struct	rusage *rusage;
206 	} *uap = (struct a *)u.u_ap;
207 	register struct rusage *rup;
208 
209 	switch (uap->who) {
210 
211 	case RUSAGE_SELF:
212 		rup = &u.u_ru;
213 		break;
214 
215 	case RUSAGE_CHILDREN:
216 		rup = &u.u_cru;
217 		break;
218 
219 	default:
220 		u.u_error = EINVAL;
221 		return;
222 	}
223 	if (copyout((caddr_t)rup, (caddr_t)uap->rusage,
224 	    sizeof (struct rusage))) {
225 		u.u_error = EFAULT;
226 		return;
227 	}
228 }
229 
230 ruadd(ru, ru2)
231 	register struct rusage *ru, *ru2;
232 {
233 	register long *ip, *ip2;
234 	register int i;
235 
236 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
237 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
238 	if (ru->ru_maxrss < ru2->ru_maxrss)
239 		ru->ru_maxrss = ru2->ru_maxrss;
240 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
241 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
242 		*ip++ += *ip2++;
243 }
244 
245 #ifndef NOCOMPAT
246 onice()
247 {
248 	register struct a {
249 		int	niceness;
250 	} *uap = (struct a *)u.u_ap;
251 	register struct proc *p = u.u_procp;
252 
253 	donice(p, (p->p_nice-NZERO)+uap->niceness);
254 }
255 
256 #include "../h/times.h"
257 
258 otimes()
259 {
260 	register struct a {
261 		struct	tms *tmsb;
262 	} *uap = (struct a *)u.u_ap;
263 	struct tms atms;
264 
265 	atms.tms_utime = scale60(&u.u_ru.ru_utime);
266 	atms.tms_stime = scale60(&u.u_ru.ru_stime);
267 	atms.tms_cutime = scale60(&u.u_cru.ru_utime);
268 	atms.tms_cstime = scale60(&u.u_cru.ru_stime);
269 	if (copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms))) {
270 		u.u_error = EFAULT;
271 		return;
272 	}
273 }
274 
275 scale60(tvp)
276 	register struct timeval *tvp;
277 {
278 
279 	return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
280 }
281 
282 #include "../h/vtimes.h"
283 
284 ovtimes()
285 {
286 	register struct a {
287 		struct	vtimes *par;
288 		struct	vtimes *chi;
289 	} *uap = (struct a *)u.u_ap;
290 	struct vtimes avt;
291 
292 	if (uap->par) {
293 		getvtimes(&u.u_ru, &avt);
294 		if (copyout((caddr_t)&avt, (caddr_t)uap->par, sizeof (avt))) {
295 			u.u_error = EFAULT;
296 			return;
297 		}
298 	}
299 	if (uap->chi) {
300 		getvtimes(&u.u_cru, &avt);
301 		if (copyout((caddr_t)&avt, (caddr_t)uap->chi, sizeof (avt))) {
302 			u.u_error = EFAULT;
303 			return;
304 		}
305 	}
306 }
307 
308 getvtimes(aru, avt)
309 	register struct rusage *aru;
310 	register struct vtimes *avt;
311 {
312 
313 	avt->vm_utime = scale60(&aru->ru_utime);
314 	avt->vm_stime = scale60(&aru->ru_stime);
315 	avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60;
316 	avt->vm_ixrss = aru->ru_ixrss / hz * 60;
317 	avt->vm_maxrss = aru->ru_maxrss;
318 	avt->vm_majflt = aru->ru_majflt;
319 	avt->vm_minflt = aru->ru_minflt;
320 	avt->vm_nswap = aru->ru_nswap;
321 	avt->vm_inblk = aru->ru_inblock;
322 	avt->vm_oublk = aru->ru_oublock;
323 }
324 
325 ovlimit()
326 {
327 
328 	u.u_error = EACCES;
329 }
330