svr4_resource.c revision 49267
1/*	Derived from:
2 *      $NetBSD: svr4_resource.c,v 1.3 1998/12/13 18:00:52 christos Exp $
3 */
4
5/*-
6 * Original copyright:
7 *
8 * Copyright (c) 1998 The NetBSD Foundation, Inc.
9 * All rights reserved.
10 *
11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Christos Zoulas.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 *    must display the following acknowledgement:
24 *        This product includes software developed by the NetBSD
25 *        Foundation, Inc. and its contributors.
26 * 4. Neither the name of The NetBSD Foundation nor the names of its
27 *    contributors may be used to endorse or promote products derived
28 *    from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 *
42 * $Id$
43 */
44
45/*
46 * Portions of this software have been derived from software contributed
47 * to the FreeBSD Project by Mark Newton.
48 *
49 * Copyright (c) 1999 Mark Newton
50 * All rights reserved.
51 *
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that the following conditions
54 * are met:
55 * 1. Redistributions of source code must retain the above copyright
56 *    notice, this list of conditions and the following disclaimer.
57 * 2. Redistributions in binary form must reproduce the above copyright
58 *    notice, this list of conditions and the following disclaimer in the
59 *    documentation and/or other materials provided with the distribution.
60 * 3. The name of the author may not be used to endorse or promote products
61 *    derived from this software without specific prior written permission
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
64 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
65 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
66 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
67 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
68 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
69 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
70 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 */
74
75#include <sys/param.h>
76#include <sys/systm.h>
77#include <sys/proc.h>
78#include <sys/file.h>
79#include <sys/resource.h>
80#include <sys/resourcevar.h>
81
82#include <svr4/svr4_types.h>
83#include <svr4/svr4_resource.h>
84#include <svr4/svr4_signal.h>
85#include <svr4/svr4_proto.h>
86#include <svr4/svr4_util.h>
87
88static __inline int svr4_to_native_rl __P((int));
89
90static __inline int
91svr4_to_native_rl(rl)
92	int rl;
93{
94	switch (rl) {
95	case SVR4_RLIMIT_CPU:
96		return RLIMIT_CPU;
97	case SVR4_RLIMIT_FSIZE:
98		return RLIMIT_FSIZE;
99	case SVR4_RLIMIT_DATA:
100		return RLIMIT_DATA;
101	case SVR4_RLIMIT_STACK:
102		return RLIMIT_STACK;
103	case SVR4_RLIMIT_CORE:
104		return RLIMIT_CORE;
105	case SVR4_RLIMIT_NOFILE:
106		return RLIMIT_NOFILE;
107	case SVR4_RLIMIT_VMEM:
108		return RLIMIT_RSS;
109	default:
110		return -1;
111	}
112}
113
114/*
115 * Check if the resource limit fits within the BSD range and it is not
116 * one of the magic SVR4 limit values
117 */
118#define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \
119	((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \
120	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \
121	((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX)
122
123#define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \
124	((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \
125	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \
126	((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX)
127
128int
129svr4_sys_getrlimit(p, uap)
130	register struct proc *p;
131	struct svr4_sys_getrlimit_args *uap;
132{
133	int rl = svr4_to_native_rl(SCARG(uap, which));
134	struct rlimit blim;
135	struct svr4_rlimit slim;
136
137	if (rl == -1)
138		return EINVAL;
139
140	blim = p->p_rlimit[rl];
141
142	/*
143	 * Our infinity, is their maxfiles.
144	 */
145	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
146		blim.rlim_max = maxfiles;
147
148	/*
149	 * If the limit can be be represented, it is returned.
150	 * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX
151	 * else return RLIM_SAVED_CUR
152	 */
153	if (blim.rlim_max == RLIM_INFINITY)
154		slim.rlim_max = SVR4_RLIM_INFINITY;
155	else if (OKLIMIT(blim.rlim_max))
156		slim.rlim_max = (svr4_rlim_t) blim.rlim_max;
157	else
158		slim.rlim_max = SVR4_RLIM_SAVED_MAX;
159
160	if (blim.rlim_cur == RLIM_INFINITY)
161		slim.rlim_cur = SVR4_RLIM_INFINITY;
162	else if (OKLIMIT(blim.rlim_cur))
163		slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur;
164	else if (blim.rlim_max == blim.rlim_cur)
165		slim.rlim_cur = SVR4_RLIM_SAVED_MAX;
166	else
167		slim.rlim_cur = SVR4_RLIM_SAVED_CUR;
168
169	return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
170}
171
172
173int
174svr4_sys_setrlimit(p, uap)
175	register struct proc *p;
176	struct svr4_sys_setrlimit_args *uap;
177{
178	int rl = svr4_to_native_rl(SCARG(uap, which));
179	struct rlimit blim, *limp;
180	struct svr4_rlimit slim;
181	int error;
182
183	if (rl == -1)
184		return EINVAL;
185
186	limp = &p->p_rlimit[rl];
187
188	if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
189		return error;
190
191	/*
192	 * if the limit is SVR4_RLIM_INFINITY, then we set it to our
193	 * unlimited.
194	 * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the
195	 * new limit to the corresponding saved hard limit, and if
196	 * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the
197	 * corresponding saved soft limit.
198	 *
199	 */
200	if (slim.rlim_max == SVR4_RLIM_INFINITY)
201		blim.rlim_max = RLIM_INFINITY;
202	else if (OKLIMIT(slim.rlim_max))
203		blim.rlim_max = (rlim_t) slim.rlim_max;
204	else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX)
205		blim.rlim_max = limp->rlim_max;
206	else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR)
207		blim.rlim_max = limp->rlim_cur;
208
209	if (slim.rlim_cur == SVR4_RLIM_INFINITY)
210		blim.rlim_cur = RLIM_INFINITY;
211	else if (OKLIMIT(slim.rlim_cur))
212		blim.rlim_cur = (rlim_t) slim.rlim_cur;
213	else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX)
214		blim.rlim_cur = limp->rlim_max;
215	else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
216		blim.rlim_cur = limp->rlim_cur;
217
218	return dosetrlimit(p, rl, &blim);
219}
220
221
222int
223svr4_sys_getrlimit64(p, uap)
224	register struct proc *p;
225	struct svr4_sys_getrlimit64_args *uap;
226{
227	int rl = svr4_to_native_rl(SCARG(uap, which));
228	struct rlimit blim;
229	struct svr4_rlimit64 slim;
230
231	if (rl == -1)
232		return EINVAL;
233
234	blim = p->p_rlimit[rl];
235
236	/*
237	 * Our infinity, is their maxfiles.
238	 */
239	if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
240		blim.rlim_max = maxfiles;
241
242	/*
243	 * If the limit can be be represented, it is returned.
244	 * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX
245	 * else return SVR4_RLIM_SAVED_CUR
246	 */
247	if (blim.rlim_max == RLIM_INFINITY)
248		slim.rlim_max = SVR4_RLIM64_INFINITY;
249	else if (OKLIMIT64(blim.rlim_max))
250		slim.rlim_max = (svr4_rlim64_t) blim.rlim_max;
251	else
252		slim.rlim_max = SVR4_RLIM64_SAVED_MAX;
253
254	if (blim.rlim_cur == RLIM_INFINITY)
255		slim.rlim_cur = SVR4_RLIM64_INFINITY;
256	else if (OKLIMIT64(blim.rlim_cur))
257		slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur;
258	else if (blim.rlim_max == blim.rlim_cur)
259		slim.rlim_cur = SVR4_RLIM64_SAVED_MAX;
260	else
261		slim.rlim_cur = SVR4_RLIM64_SAVED_CUR;
262
263	return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
264}
265
266
267int
268svr4_sys_setrlimit64(p, uap)
269	register struct proc *p;
270	struct svr4_sys_setrlimit64_args *uap;
271{
272	int rl = svr4_to_native_rl(SCARG(uap, which));
273	struct rlimit blim, *limp;
274	struct svr4_rlimit64 slim;
275	int error;
276
277	if (rl == -1)
278		return EINVAL;
279
280	limp = &p->p_rlimit[rl];
281
282	if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
283		return error;
284
285	/*
286	 * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
287	 * unlimited.
288	 * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
289	 * new limit to the corresponding saved hard limit, and if
290	 * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
291	 * corresponding saved soft limit.
292	 *
293	 */
294	if (slim.rlim_max == SVR4_RLIM64_INFINITY)
295		blim.rlim_max = RLIM_INFINITY;
296	else if (OKLIMIT64(slim.rlim_max))
297		blim.rlim_max = (rlim_t) slim.rlim_max;
298	else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
299		blim.rlim_max = limp->rlim_max;
300	else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
301		blim.rlim_max = limp->rlim_cur;
302
303	if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
304		blim.rlim_cur = RLIM_INFINITY;
305	else if (OKLIMIT64(slim.rlim_cur))
306		blim.rlim_cur = (rlim_t) slim.rlim_cur;
307	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
308		blim.rlim_cur = limp->rlim_max;
309	else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
310		blim.rlim_cur = limp->rlim_cur;
311
312	return dosetrlimit(p, rl, &blim);
313}
314