xref: /original-bsd/sys/kern/kern_resource.c (revision 0f30d223)
1 /*	kern_resource.c	6.5	85/03/08	*/
2 
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"
14 
15 /*
16  * Resource controls and accounting.
17  */
18 
19 getpriority()
20 {
21 	register struct a {
22 		int	which;
23 		int	who;
24 	} *uap = (struct a *)u.u_ap;
25 	register struct proc *p;
26 	int low = PRIO_MAX + 1;
27 
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 		low = p->p_nice;
38 		break;
39 
40 	case PRIO_PGRP:
41 		if (uap->who == 0)
42 			uap->who = u.u_procp->p_pgrp;
43 		for (p = allproc; p != NULL; p = p->p_nxt) {
44 			if (p->p_pgrp == uap->who &&
45 			    p->p_nice < low)
46 				low = p->p_nice;
47 		}
48 		break;
49 
50 	case PRIO_USER:
51 		if (uap->who == 0)
52 			uap->who = u.u_uid;
53 		for (p = allproc; p != NULL; p = p->p_nxt) {
54 			if (p->p_uid == uap->who &&
55 			    p->p_nice < low)
56 				low = p->p_nice;
57 		}
58 		break;
59 
60 	default:
61 		u.u_error = EINVAL;
62 		return;
63 	}
64 	if (low == PRIO_MAX + 1) {
65 		u.u_error = ESRCH;
66 		return;
67 	}
68 	u.u_r.r_val1 = low;
69 }
70 
71 setpriority()
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;
79 	int found = 0;
80 
81 	switch (uap->which) {
82 
83 	case PRIO_PROCESS:
84 		if (uap->who == 0)
85 			p = u.u_procp;
86 		else
87 			p = pfind(uap->who);
88 		if (p == 0)
89 			return;
90 		donice(p, uap->prio);
91 		found++;
92 		break;
93 
94 	case PRIO_PGRP:
95 		if (uap->who == 0)
96 			uap->who = u.u_procp->p_pgrp;
97 		for (p = allproc; p != NULL; p = p->p_nxt)
98 			if (p->p_pgrp == uap->who) {
99 				donice(p, uap->prio);
100 				found++;
101 			}
102 		break;
103 
104 	case PRIO_USER:
105 		if (uap->who == 0)
106 			uap->who = u.u_uid;
107 		for (p = allproc; p != NULL; p = p->p_nxt)
108 			if (p->p_uid == uap->who) {
109 				donice(p, uap->prio);
110 				found++;
111 			}
112 		break;
113 
114 	default:
115 		u.u_error = EINVAL;
116 		return;
117 	}
118 	if (found == 0)
119 		u.u_error = ESRCH;
120 }
121 
122 donice(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) {
129 		u.u_error = EACCES;
130 		return;
131 	}
132 	if (n > PRIO_MAX)
133 		n = PRIO_MAX;
134 	if (n < PRIO_MIN)
135 		n = PRIO_MIN;
136 	if (n < p->p_nice && !suser()) {
137 		u.u_error = EACCES;
138 		return;
139 	}
140 	p->p_nice = n;
141 	(void) setpri(p);
142 }
143 
144 setrlimit()
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;
152 	extern int maxdmap;
153 
154 	if (uap->which >= RLIM_NLIMITS) {
155 		u.u_error = EINVAL;
156 		return;
157 	}
158 	alimp = &u.u_rlimit[uap->which];
159 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
160 		sizeof (struct rlimit));
161 	if (u.u_error)
162 		return;
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 > maxdmap)
170 			alim.rlim_cur = maxdmap;
171 		if (alim.rlim_max > maxdmap)
172 			alim.rlim_max = maxdmap;
173 		break;
174 
175 	case RLIMIT_STACK:
176 		if (alim.rlim_cur > maxdmap)
177 			alim.rlim_cur = maxdmap;
178 		if (alim.rlim_max > maxdmap)
179 			alim.rlim_max = maxdmap;
180 		break;
181 	}
182 	*alimp = alim;
183 	if (uap->which == RLIMIT_RSS)
184 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
185 }
186 
187 getrlimit()
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 	}
198 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
199 	    sizeof (struct rlimit));
200 }
201 
202 getrusage()
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 	}
224 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
225 	    sizeof (struct rusage));
226 }
227 
228 ruadd(ru, ru2)
229 	register struct rusage *ru, *ru2;
230 {
231 	register long *ip, *ip2;
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 }
242