Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / emulation / svr4 / svr4_resource.c
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  * $FreeBSD: src/sys/svr4/svr4_resource.c,v 1.4.2.1 2002/09/02 21:22:54 dillon Exp $
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.h>
83 #include <svr4/svr4_types.h>
84 #include <svr4/svr4_resource.h>
85 #include <svr4/svr4_signal.h>
86 #include <svr4/svr4_proto.h>
87 #include <svr4/svr4_util.h>
88
89 static __inline int svr4_to_native_rl __P((int));
90
91 static __inline int
92 svr4_to_native_rl(rl)
93         int rl;
94 {
95         switch (rl) {
96         case SVR4_RLIMIT_CPU:
97                 return RLIMIT_CPU;
98         case SVR4_RLIMIT_FSIZE:
99                 return RLIMIT_FSIZE;
100         case SVR4_RLIMIT_DATA:
101                 return RLIMIT_DATA;
102         case SVR4_RLIMIT_STACK:
103                 return RLIMIT_STACK;
104         case SVR4_RLIMIT_CORE:
105                 return RLIMIT_CORE;
106         case SVR4_RLIMIT_NOFILE:
107                 return RLIMIT_NOFILE;
108         case SVR4_RLIMIT_VMEM:
109                 return RLIMIT_VMEM;
110         default:
111                 return -1;
112         }
113 }
114
115 /*
116  * Check if the resource limit fits within the BSD range and it is not
117  * one of the magic SVR4 limit values
118  */
119 #define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \
120         ((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \
121         ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \
122         ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX)
123
124 #define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \
125         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \
126         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \
127         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX)
128
129 int
130 svr4_sys_getrlimit(p, uap)
131         register struct proc *p;
132         struct svr4_sys_getrlimit_args *uap;
133 {
134         int rl = svr4_to_native_rl(SCARG(uap, which));
135         struct rlimit blim;
136         struct svr4_rlimit slim;
137
138         if (rl == -1)
139                 return EINVAL;
140
141         blim = p->p_rlimit[rl];
142
143         /*
144          * Our infinity, is their maxfiles.
145          */
146         if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
147                 blim.rlim_max = maxfiles;
148
149         /*
150          * If the limit can be be represented, it is returned.
151          * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX
152          * else return RLIM_SAVED_CUR
153          */
154         if (blim.rlim_max == RLIM_INFINITY)
155                 slim.rlim_max = SVR4_RLIM_INFINITY;
156         else if (OKLIMIT(blim.rlim_max))
157                 slim.rlim_max = (svr4_rlim_t) blim.rlim_max;
158         else
159                 slim.rlim_max = SVR4_RLIM_SAVED_MAX;
160
161         if (blim.rlim_cur == RLIM_INFINITY)
162                 slim.rlim_cur = SVR4_RLIM_INFINITY;
163         else if (OKLIMIT(blim.rlim_cur))
164                 slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur;
165         else if (blim.rlim_max == blim.rlim_cur)
166                 slim.rlim_cur = SVR4_RLIM_SAVED_MAX;
167         else
168                 slim.rlim_cur = SVR4_RLIM_SAVED_CUR;
169
170         return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
171 }
172
173
174 int
175 svr4_sys_setrlimit(p, uap)
176         register struct proc *p;
177         struct svr4_sys_setrlimit_args *uap;
178 {
179         int rl = svr4_to_native_rl(SCARG(uap, which));
180         struct rlimit blim, *limp;
181         struct svr4_rlimit slim;
182         int error;
183
184         if (rl == -1)
185                 return EINVAL;
186
187         limp = &p->p_rlimit[rl];
188
189         if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
190                 return error;
191
192         /*
193          * if the limit is SVR4_RLIM_INFINITY, then we set it to our
194          * unlimited.
195          * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the
196          * new limit to the corresponding saved hard limit, and if
197          * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the
198          * corresponding saved soft limit.
199          *
200          */
201         if (slim.rlim_max == SVR4_RLIM_INFINITY)
202                 blim.rlim_max = RLIM_INFINITY;
203         else if (OKLIMIT(slim.rlim_max))
204                 blim.rlim_max = (rlim_t) slim.rlim_max;
205         else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX)
206                 blim.rlim_max = limp->rlim_max;
207         else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR)
208                 blim.rlim_max = limp->rlim_cur;
209
210         if (slim.rlim_cur == SVR4_RLIM_INFINITY)
211                 blim.rlim_cur = RLIM_INFINITY;
212         else if (OKLIMIT(slim.rlim_cur))
213                 blim.rlim_cur = (rlim_t) slim.rlim_cur;
214         else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX)
215                 blim.rlim_cur = limp->rlim_max;
216         else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
217                 blim.rlim_cur = limp->rlim_cur;
218
219         return dosetrlimit(p, rl, &blim);
220 }
221
222
223 int
224 svr4_sys_getrlimit64(p, uap)
225         register struct proc *p;
226         struct svr4_sys_getrlimit64_args *uap;
227 {
228         int rl = svr4_to_native_rl(SCARG(uap, which));
229         struct rlimit blim;
230         struct svr4_rlimit64 slim;
231
232         if (rl == -1)
233                 return EINVAL;
234
235         blim = p->p_rlimit[rl];
236
237         /*
238          * Our infinity, is their maxfiles.
239          */
240         if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
241                 blim.rlim_max = maxfiles;
242
243         /*
244          * If the limit can be be represented, it is returned.
245          * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX
246          * else return SVR4_RLIM_SAVED_CUR
247          */
248         if (blim.rlim_max == RLIM_INFINITY)
249                 slim.rlim_max = SVR4_RLIM64_INFINITY;
250         else if (OKLIMIT64(blim.rlim_max))
251                 slim.rlim_max = (svr4_rlim64_t) blim.rlim_max;
252         else
253                 slim.rlim_max = SVR4_RLIM64_SAVED_MAX;
254
255         if (blim.rlim_cur == RLIM_INFINITY)
256                 slim.rlim_cur = SVR4_RLIM64_INFINITY;
257         else if (OKLIMIT64(blim.rlim_cur))
258                 slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur;
259         else if (blim.rlim_max == blim.rlim_cur)
260                 slim.rlim_cur = SVR4_RLIM64_SAVED_MAX;
261         else
262                 slim.rlim_cur = SVR4_RLIM64_SAVED_CUR;
263
264         return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
265 }
266
267
268 int
269 svr4_sys_setrlimit64(p, uap)
270         register struct proc *p;
271         struct svr4_sys_setrlimit64_args *uap;
272 {
273         int rl = svr4_to_native_rl(SCARG(uap, which));
274         struct rlimit blim, *limp;
275         struct svr4_rlimit64 slim;
276         int error;
277
278         if (rl == -1)
279                 return EINVAL;
280
281         limp = &p->p_rlimit[rl];
282
283         if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
284                 return error;
285
286         /*
287          * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
288          * unlimited.
289          * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
290          * new limit to the corresponding saved hard limit, and if
291          * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
292          * corresponding saved soft limit.
293          *
294          */
295         if (slim.rlim_max == SVR4_RLIM64_INFINITY)
296                 blim.rlim_max = RLIM_INFINITY;
297         else if (OKLIMIT64(slim.rlim_max))
298                 blim.rlim_max = (rlim_t) slim.rlim_max;
299         else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
300                 blim.rlim_max = limp->rlim_max;
301         else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
302                 blim.rlim_max = limp->rlim_cur;
303
304         if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
305                 blim.rlim_cur = RLIM_INFINITY;
306         else if (OKLIMIT64(slim.rlim_cur))
307                 blim.rlim_cur = (rlim_t) slim.rlim_cur;
308         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
309                 blim.rlim_cur = limp->rlim_max;
310         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
311                 blim.rlim_cur = limp->rlim_cur;
312
313         return dosetrlimit(p, rl, &blim);
314 }