* Use id(1) instead of grep(1) to detect the presence of the smmsp
[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  * $DragonFly: src/sys/emulation/svr4/Attic/svr4_resource.c,v 1.6 2003/11/04 05:01:10 daver Exp $
44  */
45
46 /*
47  * Portions of this software have been derived from software contributed
48  * to the FreeBSD Project by Mark Newton.
49  *
50  * Copyright (c) 1999 Mark Newton
51  * All rights reserved.
52  * 
53  * Redistribution and use in source and binary forms, with or without
54  * modification, are permitted provided that the following conditions
55  * are met:
56  * 1. Redistributions of source code must retain the above copyright
57  *    notice, this list of conditions and the following disclaimer.
58  * 2. Redistributions in binary form must reproduce the above copyright
59  *    notice, this list of conditions and the following disclaimer in the
60  *    documentation and/or other materials provided with the distribution.
61  * 3. The name of the author may not be used to endorse or promote products
62  *    derived from this software without specific prior written permission
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
65  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
66  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
67  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
68  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
69  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
70  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
71  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
73  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74  */
75
76 #include <sys/param.h>
77 #include <sys/systm.h>
78 #include <sys/proc.h>
79 #include <sys/file.h>
80 #include <sys/kern_syscall.h>
81 #include <sys/resource.h>
82 #include <sys/resourcevar.h>
83
84 #include "svr4.h"
85 #include "svr4_types.h"
86 #include "svr4_resource.h"
87 #include "svr4_signal.h"
88 #include "svr4_proto.h"
89 #include "svr4_util.h"
90
91 static __inline int svr4_to_native_rl (int);
92
93 static __inline int
94 svr4_to_native_rl(rl)
95         int rl;
96 {
97         switch (rl) {
98         case SVR4_RLIMIT_CPU:
99                 return RLIMIT_CPU;
100         case SVR4_RLIMIT_FSIZE:
101                 return RLIMIT_FSIZE;
102         case SVR4_RLIMIT_DATA:
103                 return RLIMIT_DATA;
104         case SVR4_RLIMIT_STACK:
105                 return RLIMIT_STACK;
106         case SVR4_RLIMIT_CORE:
107                 return RLIMIT_CORE;
108         case SVR4_RLIMIT_NOFILE:
109                 return RLIMIT_NOFILE;
110         case SVR4_RLIMIT_VMEM:
111                 return RLIMIT_VMEM;
112         default:
113                 return -1;
114         }
115 }
116
117 /*
118  * Check if the resource limit fits within the BSD range and it is not
119  * one of the magic SVR4 limit values
120  */
121 #define OKLIMIT(l) (((int32_t)(l)) >= 0 && ((int32_t)(l)) < 0x7fffffff && \
122         ((svr4_rlim_t)(l)) != SVR4_RLIM_INFINITY && \
123         ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_CUR && \
124         ((svr4_rlim_t)(l)) != SVR4_RLIM_SAVED_MAX)
125
126 #define OKLIMIT64(l) (((rlim_t)(l)) >= 0 && ((rlim_t)(l)) < RLIM_INFINITY && \
127         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_INFINITY && \
128         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_CUR && \
129         ((svr4_rlim64_t)(l)) != SVR4_RLIM64_SAVED_MAX)
130
131 int
132 svr4_sys_getrlimit(struct svr4_sys_getrlimit_args *uap)
133 {
134         struct proc *p = curproc;
135         int rl = svr4_to_native_rl(SCARG(uap, which));
136         struct rlimit blim;
137         struct svr4_rlimit slim;
138
139         if (rl == -1)
140                 return EINVAL;
141
142         blim = p->p_rlimit[rl];
143
144         /*
145          * Our infinity, is their maxfiles.
146          */
147         if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
148                 blim.rlim_max = maxfiles;
149
150         /*
151          * If the limit can be be represented, it is returned.
152          * Otherwise, if rlim_cur == rlim_max, return RLIM_SAVED_MAX
153          * else return RLIM_SAVED_CUR
154          */
155         if (blim.rlim_max == RLIM_INFINITY)
156                 slim.rlim_max = SVR4_RLIM_INFINITY;
157         else if (OKLIMIT(blim.rlim_max))
158                 slim.rlim_max = (svr4_rlim_t) blim.rlim_max;
159         else
160                 slim.rlim_max = SVR4_RLIM_SAVED_MAX;
161
162         if (blim.rlim_cur == RLIM_INFINITY)
163                 slim.rlim_cur = SVR4_RLIM_INFINITY;
164         else if (OKLIMIT(blim.rlim_cur))
165                 slim.rlim_cur = (svr4_rlim_t) blim.rlim_cur;
166         else if (blim.rlim_max == blim.rlim_cur)
167                 slim.rlim_cur = SVR4_RLIM_SAVED_MAX;
168         else
169                 slim.rlim_cur = SVR4_RLIM_SAVED_CUR;
170
171         return copyout(&slim, SCARG(uap, rlp), sizeof(*SCARG(uap, rlp)));
172 }
173
174
175 int
176 svr4_sys_setrlimit(struct svr4_sys_setrlimit_args *uap)
177 {
178         struct proc *p = curproc;
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 kern_setrlimit(rl, &blim);
220 }
221
222
223 int
224 svr4_sys_getrlimit64(struct svr4_sys_getrlimit64_args *uap)
225 {
226         struct proc *p = curproc;
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
267 int
268 svr4_sys_setrlimit64(struct svr4_sys_setrlimit64_args *uap)
269 {
270         struct proc *p = curproc;
271         int rl = svr4_to_native_rl(SCARG(uap, which));
272         struct rlimit blim, *limp;
273         struct svr4_rlimit64 slim;
274         int error;
275
276         if (rl == -1)
277                 return EINVAL;
278
279         limp = &p->p_rlimit[rl];
280
281         if ((error = copyin(SCARG(uap, rlp), &slim, sizeof(slim))) != 0)
282                 return error;
283
284         /*
285          * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
286          * unlimited.
287          * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
288          * new limit to the corresponding saved hard limit, and if
289          * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
290          * corresponding saved soft limit.
291          *
292          */
293         if (slim.rlim_max == SVR4_RLIM64_INFINITY)
294                 blim.rlim_max = RLIM_INFINITY;
295         else if (OKLIMIT64(slim.rlim_max))
296                 blim.rlim_max = (rlim_t) slim.rlim_max;
297         else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
298                 blim.rlim_max = limp->rlim_max;
299         else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
300                 blim.rlim_max = limp->rlim_cur;
301
302         if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
303                 blim.rlim_cur = RLIM_INFINITY;
304         else if (OKLIMIT64(slim.rlim_cur))
305                 blim.rlim_cur = (rlim_t) slim.rlim_cur;
306         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
307                 blim.rlim_cur = limp->rlim_max;
308         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
309                 blim.rlim_cur = limp->rlim_cur;
310
311         return kern_setrlimit(rl, &blim);
312 }