xref: /original-bsd/sys/kern/kern_resource.c (revision c43e4352)
1 /*	kern_resource.c	6.1	83/07/29	*/
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 #include "../h/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 
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;
38 		u.u_r.r_val1 = p->p_nice;
39 		u.u_error = 0;
40 		break;
41 
42 	case PRIO_PGRP:
43 		if (uap->who == 0)
44 			uap->who = u.u_procp->p_pgrp;
45 		for (p = proc; p < procNPROC; p++) {
46 			if (p->p_stat == NULL)
47 				continue;
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 			}
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 		}
68 		break;
69 
70 	default:
71 		u.u_error = EINVAL;
72 		break;
73 	}
74 	u.u_r.r_val1 -= NZERO;
75 }
76 
77 setpriority()
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:
90 		if (uap->who == 0)
91 			p = u.u_procp;
92 		else
93 			p = pfind(uap->who);
94 		if (p == 0)
95 			return;
96 		donice(p, uap->prio);
97 		break;
98 
99 	case PRIO_PGRP:
100 		if (uap->who == 0)
101 			uap->who = u.u_procp->p_pgrp;
102 		for (p = proc; p < procNPROC; p++)
103 			if (p->p_pgrp == uap->who)
104 				donice(p, uap->prio);
105 		break;
106 
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 
115 	default:
116 		u.u_error = EINVAL;
117 		break;
118 	}
119 }
120 
121 donice(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) {
128 		u.u_error = EACCES;
129 		return;
130 	}
131 	n += NZERO;
132 	if (n >= 2*NZERO)
133 		n = 2*NZERO - 1;
134 	if (n < 0)
135 		n = 0;
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 	if (u.u_error == ESRCH)
143 		u.u_error = 0;
144 }
145 
146 setrlimit()
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];
160 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
161 		sizeof (struct rlimit));
162 	if (u.u_error)
163 		return;
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 
184 getrlimit()
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 	}
195 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
196 	    sizeof (struct rlimit));
197 }
198 
199 getrusage()
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 	}
221 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
222 	    sizeof (struct rusage));
223 }
224 
225 ruadd(ru, ru2)
226 	register struct rusage *ru, *ru2;
227 {
228 	register long *ip, *ip2;
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 }
239