]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/compat/svr4/svr4_resource.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / compat / svr4 / svr4_resource.c
1 /*-
2  * Copyright (c) 1998 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Christos Zoulas.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *        This product includes software developed by the NetBSD
19  *        Foundation, Inc. and its contributors.
20  * 4. Neither the name of The NetBSD Foundation nor the names of its
21  *    contributors may be used to endorse or promote products derived
22  *    from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 /*-
37  * Portions of this software have been derived from software contributed
38  * to the FreeBSD Project by Mark Newton.
39  *
40  * Copyright (c) 1999 Mark Newton
41  * All rights reserved.
42  * 
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. The name of the author may not be used to endorse or promote products
52  *    derived from this software without specific prior written permission
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  *
65  * Derived from: $NetBSD: svr4_resource.c,v 1.3 1998/12/13 18:00:52 christos Exp $
66  */
67
68 #include <sys/cdefs.h>
69 __FBSDID("$FreeBSD$");
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/file.h>
74 #include <sys/lock.h>
75 #include <sys/mutex.h>
76 #include <sys/proc.h>
77 #include <sys/resource.h>
78 #include <sys/resourcevar.h>
79 #include <sys/syscallsubr.h>
80
81 #include <compat/svr4/svr4.h>
82 #include <compat/svr4/svr4_types.h>
83 #include <compat/svr4/svr4_resource.h>
84 #include <compat/svr4/svr4_signal.h>
85 #include <compat/svr4/svr4_proto.h>
86 #include <compat/svr4/svr4_util.h>
87
88 static __inline int svr4_to_native_rl(int);
89
90 static __inline int
91 svr4_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_VMEM;
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
128 int
129 svr4_sys_getrlimit(td, uap)
130         struct thread *td;
131         struct svr4_sys_getrlimit_args *uap;
132 {
133         int rl = svr4_to_native_rl(uap->which);
134         struct rlimit blim;
135         struct svr4_rlimit slim;
136
137         if (rl == -1)
138                 return EINVAL;
139
140         PROC_LOCK(td->td_proc);
141         lim_rlimit(td->td_proc, rl, &blim);
142         PROC_UNLOCK(td->td_proc);
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, uap->rlp, sizeof(*uap->rlp));
172 }
173
174
175 int
176 svr4_sys_setrlimit(td, uap)
177         struct thread *td;
178         struct svr4_sys_setrlimit_args *uap;
179 {
180         int rl = svr4_to_native_rl(uap->which);
181         struct rlimit blim, curlim;
182         struct svr4_rlimit slim;
183         int error;
184
185         if (rl == -1)
186                 return EINVAL;
187
188         if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
189                 return error;
190
191         PROC_LOCK(td->td_proc);
192         lim_rlimit(td->td_proc, rl, &curlim);
193         PROC_UNLOCK(td->td_proc);
194
195         /*
196          * if the limit is SVR4_RLIM_INFINITY, then we set it to our
197          * unlimited.
198          * We should also: If it is SVR4_RLIM_SAVED_MAX, we should set the
199          * new limit to the corresponding saved hard limit, and if
200          * it is equal to SVR4_RLIM_SAVED_CUR, we should set it to the
201          * corresponding saved soft limit.
202          *
203          */
204         if (slim.rlim_max == SVR4_RLIM_INFINITY)
205                 blim.rlim_max = RLIM_INFINITY;
206         else if (OKLIMIT(slim.rlim_max))
207                 blim.rlim_max = (rlim_t) slim.rlim_max;
208         else if (slim.rlim_max == SVR4_RLIM_SAVED_MAX)
209                 blim.rlim_max = curlim.rlim_max;
210         else if (slim.rlim_max == SVR4_RLIM_SAVED_CUR)
211                 blim.rlim_max = curlim.rlim_cur;
212
213         if (slim.rlim_cur == SVR4_RLIM_INFINITY)
214                 blim.rlim_cur = RLIM_INFINITY;
215         else if (OKLIMIT(slim.rlim_cur))
216                 blim.rlim_cur = (rlim_t) slim.rlim_cur;
217         else if (slim.rlim_cur == SVR4_RLIM_SAVED_MAX)
218                 blim.rlim_cur = curlim.rlim_max;
219         else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
220                 blim.rlim_cur = curlim.rlim_cur;
221
222         return (kern_setrlimit(td, rl, &blim));
223 }
224
225
226 int
227 svr4_sys_getrlimit64(td, uap)
228         struct thread *td;
229         struct svr4_sys_getrlimit64_args *uap;
230 {
231         int rl = svr4_to_native_rl(uap->which);
232         struct rlimit blim;
233         struct svr4_rlimit64 slim;
234
235         if (rl == -1)
236                 return EINVAL;
237
238         PROC_LOCK(td->td_proc);
239         lim_rlimit(td->td_proc, rl, &blim);
240         PROC_UNLOCK(td->td_proc);
241
242         /*
243          * Our infinity, is their maxfiles.
244          */
245         if (rl == RLIMIT_NOFILE && blim.rlim_max == RLIM_INFINITY)
246                 blim.rlim_max = maxfiles;
247
248         /*
249          * If the limit can be be represented, it is returned.
250          * Otherwise, if rlim_cur == rlim_max, return SVR4_RLIM_SAVED_MAX
251          * else return SVR4_RLIM_SAVED_CUR
252          */
253         if (blim.rlim_max == RLIM_INFINITY)
254                 slim.rlim_max = SVR4_RLIM64_INFINITY;
255         else if (OKLIMIT64(blim.rlim_max))
256                 slim.rlim_max = (svr4_rlim64_t) blim.rlim_max;
257         else
258                 slim.rlim_max = SVR4_RLIM64_SAVED_MAX;
259
260         if (blim.rlim_cur == RLIM_INFINITY)
261                 slim.rlim_cur = SVR4_RLIM64_INFINITY;
262         else if (OKLIMIT64(blim.rlim_cur))
263                 slim.rlim_cur = (svr4_rlim64_t) blim.rlim_cur;
264         else if (blim.rlim_max == blim.rlim_cur)
265                 slim.rlim_cur = SVR4_RLIM64_SAVED_MAX;
266         else
267                 slim.rlim_cur = SVR4_RLIM64_SAVED_CUR;
268
269         return copyout(&slim, uap->rlp, sizeof(*uap->rlp));
270 }
271
272
273 int
274 svr4_sys_setrlimit64(td, uap)
275         struct thread *td;
276         struct svr4_sys_setrlimit64_args *uap;
277 {
278         int rl = svr4_to_native_rl(uap->which);
279         struct rlimit blim, curlim;
280         struct svr4_rlimit64 slim;
281         int error;
282
283         if (rl == -1)
284                 return EINVAL;
285
286         if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
287                 return error;
288
289         PROC_LOCK(td->td_proc);
290         lim_rlimit(td->td_proc, rl, &curlim);
291         PROC_UNLOCK(td->td_proc);
292
293         /*
294          * if the limit is SVR4_RLIM64_INFINITY, then we set it to our
295          * unlimited.
296          * We should also: If it is SVR4_RLIM64_SAVED_MAX, we should set the
297          * new limit to the corresponding saved hard limit, and if
298          * it is equal to SVR4_RLIM64_SAVED_CUR, we should set it to the
299          * corresponding saved soft limit.
300          *
301          */
302         if (slim.rlim_max == SVR4_RLIM64_INFINITY)
303                 blim.rlim_max = RLIM_INFINITY;
304         else if (OKLIMIT64(slim.rlim_max))
305                 blim.rlim_max = (rlim_t) slim.rlim_max;
306         else if (slim.rlim_max == SVR4_RLIM64_SAVED_MAX)
307                 blim.rlim_max = curlim.rlim_max;
308         else if (slim.rlim_max == SVR4_RLIM64_SAVED_CUR)
309                 blim.rlim_max = curlim.rlim_cur;
310
311         if (slim.rlim_cur == SVR4_RLIM64_INFINITY)
312                 blim.rlim_cur = RLIM_INFINITY;
313         else if (OKLIMIT64(slim.rlim_cur))
314                 blim.rlim_cur = (rlim_t) slim.rlim_cur;
315         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_MAX)
316                 blim.rlim_cur = curlim.rlim_max;
317         else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
318                 blim.rlim_cur = curlim.rlim_cur;
319
320         return (kern_setrlimit(td, rl, &blim));
321 }