1 | This file is ulimit.def, from which is created ulimit.c.
|
---|
2 | It implements the builtin "ulimit" in Bash.
|
---|
3 |
|
---|
4 | Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
5 |
|
---|
6 | This file is part of GNU Bash, the Bourne Again SHell.
|
---|
7 |
|
---|
8 | Bash is free software; you can redistribute it and/or modify it under
|
---|
9 | the terms of the GNU General Public License as published by the Free
|
---|
10 | Software Foundation; either version 2, or (at your option) any later
|
---|
11 | version.
|
---|
12 |
|
---|
13 | Bash is distributed in the hope that it will be useful, but WITHOUT ANY
|
---|
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
---|
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
---|
16 | for more details.
|
---|
17 |
|
---|
18 | You should have received a copy of the GNU General Public License along
|
---|
19 | with Bash; see the file COPYING. If not, write to the Free Software
|
---|
20 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
---|
21 |
|
---|
22 | $PRODUCES ulimit.c
|
---|
23 |
|
---|
24 | $BUILTIN ulimit
|
---|
25 | $FUNCTION ulimit_builtin
|
---|
26 | $DEPENDS_ON !_MINIX
|
---|
27 | $SHORT_DOC ulimit [-SHacdfilmnpqstuvx] [limit]
|
---|
28 | Ulimit provides control over the resources available to processes
|
---|
29 | started by the shell, on systems that allow such control. If an
|
---|
30 | option is given, it is interpreted as follows:
|
---|
31 |
|
---|
32 | -S use the `soft' resource limit
|
---|
33 | -H use the `hard' resource limit
|
---|
34 | -a all current limits are reported
|
---|
35 | -c the maximum size of core files created
|
---|
36 | -d the maximum size of a process's data segment
|
---|
37 | -f the maximum size of files created by the shell
|
---|
38 | -i the maximum number of pending signals
|
---|
39 | -l the maximum size a process may lock into memory
|
---|
40 | -m the maximum resident set size
|
---|
41 | -n the maximum number of open file descriptors
|
---|
42 | -p the pipe buffer size
|
---|
43 | -q the maximum number of bytes in POSIX message queues
|
---|
44 | -s the maximum stack size
|
---|
45 | -t the maximum amount of cpu time in seconds
|
---|
46 | -u the maximum number of user processes
|
---|
47 | -v the size of virtual memory
|
---|
48 | -x the maximum number of file locks
|
---|
49 |
|
---|
50 | If LIMIT is given, it is the new value of the specified resource;
|
---|
51 | the special LIMIT values `soft', `hard', and `unlimited' stand for
|
---|
52 | the current soft limit, the current hard limit, and no limit, respectively.
|
---|
53 | Otherwise, the current value of the specified resource is printed.
|
---|
54 | If no option is given, then -f is assumed. Values are in 1024-byte
|
---|
55 | increments, except for -t, which is in seconds, -p, which is in
|
---|
56 | increments of 512 bytes, and -u, which is an unscaled number of
|
---|
57 | processes.
|
---|
58 | $END
|
---|
59 |
|
---|
60 | #if !defined (_MINIX)
|
---|
61 |
|
---|
62 | #include <config.h>
|
---|
63 |
|
---|
64 | #include "../bashtypes.h"
|
---|
65 | #ifndef _MINIX
|
---|
66 | # include <sys/param.h>
|
---|
67 | #endif
|
---|
68 |
|
---|
69 | #if defined (HAVE_UNISTD_H)
|
---|
70 | # include <unistd.h>
|
---|
71 | #endif
|
---|
72 |
|
---|
73 | #include <stdio.h>
|
---|
74 | #include <errno.h>
|
---|
75 |
|
---|
76 | #include "../bashintl.h"
|
---|
77 |
|
---|
78 | #include "../shell.h"
|
---|
79 | #include "common.h"
|
---|
80 | #include "bashgetopt.h"
|
---|
81 | #include "pipesize.h"
|
---|
82 |
|
---|
83 | #if !defined (errno)
|
---|
84 | extern int errno;
|
---|
85 | #endif
|
---|
86 |
|
---|
87 | /* For some reason, HPUX chose to make these definitions visible only if
|
---|
88 | _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
|
---|
89 | and #undef it afterward. */
|
---|
90 | #if defined (HAVE_RESOURCE)
|
---|
91 | # include <sys/time.h>
|
---|
92 | # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
---|
93 | # define _KERNEL
|
---|
94 | # endif
|
---|
95 | # include <sys/resource.h>
|
---|
96 | # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
|
---|
97 | # undef _KERNEL
|
---|
98 | # endif
|
---|
99 | #else
|
---|
100 | # include <sys/times.h>
|
---|
101 | #endif
|
---|
102 |
|
---|
103 | #if defined (HAVE_LIMITS_H)
|
---|
104 | # include <limits.h>
|
---|
105 | #endif
|
---|
106 |
|
---|
107 | /* Check for the most basic symbols. If they aren't present, this
|
---|
108 | system's <sys/resource.h> isn't very useful to us. */
|
---|
109 | #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
|
---|
110 | # undef HAVE_RESOURCE
|
---|
111 | #endif
|
---|
112 |
|
---|
113 | #if !defined (RLIMTYPE)
|
---|
114 | # define RLIMTYPE long
|
---|
115 | # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
|
---|
116 | # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
---|
117 | #endif
|
---|
118 |
|
---|
119 | /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
|
---|
120 | #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
|
---|
121 | # define RLIMIT_NOFILE RLIMIT_OFILE
|
---|
122 | #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
|
---|
123 |
|
---|
124 | /* Some systems have these, some do not. */
|
---|
125 | #ifdef RLIMIT_FSIZE
|
---|
126 | # define RLIMIT_FILESIZE RLIMIT_FSIZE
|
---|
127 | #else
|
---|
128 | # define RLIMIT_FILESIZE 256
|
---|
129 | #endif
|
---|
130 |
|
---|
131 | #define RLIMIT_PIPESIZE 257
|
---|
132 |
|
---|
133 | #ifdef RLIMIT_NOFILE
|
---|
134 | # define RLIMIT_OPENFILES RLIMIT_NOFILE
|
---|
135 | #else
|
---|
136 | # define RLIMIT_OPENFILES 258
|
---|
137 | #endif
|
---|
138 |
|
---|
139 | #ifdef RLIMIT_VMEM
|
---|
140 | # define RLIMIT_VIRTMEM RLIMIT_VMEM
|
---|
141 | # define RLIMIT_VMBLKSZ 1024
|
---|
142 | #else
|
---|
143 | # ifdef RLIMIT_AS
|
---|
144 | # define RLIMIT_VIRTMEM RLIMIT_AS
|
---|
145 | # define RLIMIT_VMBLKSZ 1024
|
---|
146 | # else
|
---|
147 | # define RLIMIT_VIRTMEM 259
|
---|
148 | # define RLIMIT_VMBLKSZ 1
|
---|
149 | # endif
|
---|
150 | #endif
|
---|
151 |
|
---|
152 | #ifdef RLIMIT_NPROC
|
---|
153 | # define RLIMIT_MAXUPROC RLIMIT_NPROC
|
---|
154 | #else
|
---|
155 | # define RLIMIT_MAXUPROC 260
|
---|
156 | #endif
|
---|
157 |
|
---|
158 | #if !defined (RLIM_INFINITY)
|
---|
159 | # define RLIM_INFINITY 0x7fffffff
|
---|
160 | #endif
|
---|
161 |
|
---|
162 | #if !defined (RLIM_SAVED_CUR)
|
---|
163 | # define RLIM_SAVED_CUR RLIM_INFINITY
|
---|
164 | #endif
|
---|
165 |
|
---|
166 | #if !defined (RLIM_SAVED_MAX)
|
---|
167 | # define RLIM_SAVED_MAX RLIM_INFINITY
|
---|
168 | #endif
|
---|
169 |
|
---|
170 | #define LIMIT_HARD 0x01
|
---|
171 | #define LIMIT_SOFT 0x02
|
---|
172 |
|
---|
173 | static int _findlim __P((int));
|
---|
174 |
|
---|
175 | static int ulimit_internal __P((int, char *, int, int));
|
---|
176 |
|
---|
177 | static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
|
---|
178 | static int set_limit __P((int, RLIMTYPE, int));
|
---|
179 |
|
---|
180 | static void printone __P((int, RLIMTYPE, int));
|
---|
181 | static void print_all_limits __P((int));
|
---|
182 |
|
---|
183 | static int set_all_limits __P((int, RLIMTYPE));
|
---|
184 |
|
---|
185 | static int filesize __P((RLIMTYPE *));
|
---|
186 | static int pipesize __P((RLIMTYPE *));
|
---|
187 | static int getmaxuprc __P((RLIMTYPE *));
|
---|
188 | static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
|
---|
189 |
|
---|
190 | typedef struct {
|
---|
191 | int option; /* The ulimit option for this limit. */
|
---|
192 | int parameter; /* Parameter to pass to get_limit (). */
|
---|
193 | int block_factor; /* Blocking factor for specific limit. */
|
---|
194 | char *description; /* Descriptive string to output. */
|
---|
195 | char *units; /* scale */
|
---|
196 | } RESOURCE_LIMITS;
|
---|
197 |
|
---|
198 | static RESOURCE_LIMITS limits[] = {
|
---|
199 | #ifdef RLIMIT_CORE
|
---|
200 | { 'c', RLIMIT_CORE, 1024, "core file size", "blocks" },
|
---|
201 | #endif
|
---|
202 | #ifdef RLIMIT_DATA
|
---|
203 | { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
|
---|
204 | #endif
|
---|
205 | { 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
|
---|
206 | #ifdef RLIMIT_SIGPENDING
|
---|
207 | { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
|
---|
208 | #endif
|
---|
209 | #ifdef RLIMIT_MEMLOCK
|
---|
210 | { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
|
---|
211 | #endif
|
---|
212 | #ifdef RLIMIT_RSS
|
---|
213 | { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
|
---|
214 | #endif /* RLIMIT_RSS */
|
---|
215 | { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
|
---|
216 | { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
|
---|
217 | #ifdef RLIMIT_MSGQUEUE
|
---|
218 | { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
|
---|
219 | #endif
|
---|
220 | #ifdef RLIMIT_STACK
|
---|
221 | { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
|
---|
222 | #endif
|
---|
223 | #ifdef RLIMIT_CPU
|
---|
224 | { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
|
---|
225 | #endif /* RLIMIT_CPU */
|
---|
226 | { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
|
---|
227 | #if defined (HAVE_RESOURCE)
|
---|
228 | { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
|
---|
229 | #endif
|
---|
230 | #ifdef RLIMIT_SWAP
|
---|
231 | { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
|
---|
232 | #endif
|
---|
233 | #ifdef RLIMIT_LOCKS
|
---|
234 | { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
|
---|
235 | #endif
|
---|
236 | { -1, -1, -1, (char *)NULL, (char *)NULL }
|
---|
237 | };
|
---|
238 | #define NCMDS (sizeof(limits) / sizeof(limits[0]))
|
---|
239 |
|
---|
240 | typedef struct _cmd {
|
---|
241 | int cmd;
|
---|
242 | char *arg;
|
---|
243 | } ULCMD;
|
---|
244 |
|
---|
245 | static ULCMD *cmdlist;
|
---|
246 | static int ncmd;
|
---|
247 | static int cmdlistsz;
|
---|
248 |
|
---|
249 | #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
|
---|
250 | long
|
---|
251 | ulimit (cmd, newlim)
|
---|
252 | int cmd;
|
---|
253 | long newlim;
|
---|
254 | {
|
---|
255 | errno = EINVAL;
|
---|
256 | return -1;
|
---|
257 | }
|
---|
258 | #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
|
---|
259 |
|
---|
260 | static int
|
---|
261 | _findlim (opt)
|
---|
262 | int opt;
|
---|
263 | {
|
---|
264 | register int i;
|
---|
265 |
|
---|
266 | for (i = 0; limits[i].option > 0; i++)
|
---|
267 | if (limits[i].option == opt)
|
---|
268 | return i;
|
---|
269 | return -1;
|
---|
270 | }
|
---|
271 |
|
---|
272 | static char optstring[4 + 2 * NCMDS];
|
---|
273 |
|
---|
274 | /* Report or set limits associated with certain per-process resources.
|
---|
275 | See the help documentation in builtins.c for a full description. */
|
---|
276 | int
|
---|
277 | ulimit_builtin (list)
|
---|
278 | register WORD_LIST *list;
|
---|
279 | {
|
---|
280 | register char *s;
|
---|
281 | int c, limind, mode, opt, all_limits;
|
---|
282 |
|
---|
283 | mode = 0;
|
---|
284 |
|
---|
285 | all_limits = 0;
|
---|
286 |
|
---|
287 | /* Idea stolen from pdksh -- build option string the first time called. */
|
---|
288 | if (optstring[0] == 0)
|
---|
289 | {
|
---|
290 | s = optstring;
|
---|
291 | *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
|
---|
292 | for (c = 0; limits[c].option > 0; c++)
|
---|
293 | {
|
---|
294 | *s++ = limits[c].option;
|
---|
295 | *s++ = ';';
|
---|
296 | }
|
---|
297 | *s = '\0';
|
---|
298 | }
|
---|
299 |
|
---|
300 | /* Initialize the command list. */
|
---|
301 | if (cmdlistsz == 0)
|
---|
302 | cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
|
---|
303 | ncmd = 0;
|
---|
304 |
|
---|
305 | reset_internal_getopt ();
|
---|
306 | while ((opt = internal_getopt (list, optstring)) != -1)
|
---|
307 | {
|
---|
308 | switch (opt)
|
---|
309 | {
|
---|
310 | case 'a':
|
---|
311 | all_limits++;
|
---|
312 | break;
|
---|
313 |
|
---|
314 | /* -S and -H are modifiers, not real options. */
|
---|
315 | case 'S':
|
---|
316 | mode |= LIMIT_SOFT;
|
---|
317 | break;
|
---|
318 |
|
---|
319 | case 'H':
|
---|
320 | mode |= LIMIT_HARD;
|
---|
321 | break;
|
---|
322 |
|
---|
323 | case '?':
|
---|
324 | builtin_usage ();
|
---|
325 | return (EX_USAGE);
|
---|
326 |
|
---|
327 | default:
|
---|
328 | if (ncmd >= cmdlistsz)
|
---|
329 | cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
|
---|
330 | cmdlist[ncmd].cmd = opt;
|
---|
331 | cmdlist[ncmd++].arg = list_optarg;
|
---|
332 | break;
|
---|
333 | }
|
---|
334 | }
|
---|
335 | list = loptend;
|
---|
336 |
|
---|
337 | if (all_limits)
|
---|
338 | {
|
---|
339 | #ifdef NOTYET
|
---|
340 | if (list) /* setting */
|
---|
341 | {
|
---|
342 | if (STREQ (list->word->word, "unlimited") == 0)
|
---|
343 | {
|
---|
344 | builtin_error (_("%s: invalid limit argument"), list->word->word);
|
---|
345 | return (EXECUTION_FAILURE);
|
---|
346 | }
|
---|
347 | return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
|
---|
348 | }
|
---|
349 | #endif
|
---|
350 | print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
|
---|
351 | return (EXECUTION_SUCCESS);
|
---|
352 | }
|
---|
353 |
|
---|
354 | /* default is `ulimit -f' */
|
---|
355 | if (ncmd == 0)
|
---|
356 | {
|
---|
357 | cmdlist[ncmd].cmd = 'f';
|
---|
358 | /* `ulimit something' is same as `ulimit -f something' */
|
---|
359 | cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
|
---|
360 | if (list)
|
---|
361 | list = list->next;
|
---|
362 | }
|
---|
363 |
|
---|
364 | /* verify each command in the list. */
|
---|
365 | for (c = 0; c < ncmd; c++)
|
---|
366 | {
|
---|
367 | limind = _findlim (cmdlist[c].cmd);
|
---|
368 | if (limind == -1)
|
---|
369 | {
|
---|
370 | builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
|
---|
371 | return (EX_USAGE);
|
---|
372 | }
|
---|
373 | }
|
---|
374 |
|
---|
375 | for (c = 0; c < ncmd; c++)
|
---|
376 | if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
|
---|
377 | return (EXECUTION_FAILURE);
|
---|
378 |
|
---|
379 | return (EXECUTION_SUCCESS);
|
---|
380 | }
|
---|
381 |
|
---|
382 | static int
|
---|
383 | ulimit_internal (cmd, cmdarg, mode, multiple)
|
---|
384 | int cmd;
|
---|
385 | char *cmdarg;
|
---|
386 | int mode, multiple;
|
---|
387 | {
|
---|
388 | int opt, limind, setting;
|
---|
389 | int block_factor;
|
---|
390 | RLIMTYPE soft_limit, hard_limit, real_limit, limit;
|
---|
391 |
|
---|
392 | setting = cmdarg != 0;
|
---|
393 | limind = _findlim (cmd);
|
---|
394 | if (mode == 0)
|
---|
395 | mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
|
---|
396 | opt = get_limit (limind, &soft_limit, &hard_limit);
|
---|
397 | if (opt < 0)
|
---|
398 | {
|
---|
399 | builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
|
---|
400 | strerror (errno));
|
---|
401 | return (EXECUTION_FAILURE);
|
---|
402 | }
|
---|
403 |
|
---|
404 | if (setting == 0) /* print the value of the specified limit */
|
---|
405 | {
|
---|
406 | printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
|
---|
407 | return (EXECUTION_SUCCESS);
|
---|
408 | }
|
---|
409 |
|
---|
410 | /* Setting the limit. */
|
---|
411 | if (STREQ (cmdarg, "hard"))
|
---|
412 | real_limit = hard_limit;
|
---|
413 | else if (STREQ (cmdarg, "soft"))
|
---|
414 | real_limit = soft_limit;
|
---|
415 | else if (STREQ (cmdarg, "unlimited"))
|
---|
416 | real_limit = RLIM_INFINITY;
|
---|
417 | else if (all_digits (cmdarg))
|
---|
418 | {
|
---|
419 | limit = string_to_rlimtype (cmdarg);
|
---|
420 | block_factor = limits[limind].block_factor;
|
---|
421 | real_limit = limit * block_factor;
|
---|
422 |
|
---|
423 | if ((real_limit / block_factor) != limit)
|
---|
424 | {
|
---|
425 | sh_erange (cmdarg, "limit");
|
---|
426 | return (EXECUTION_FAILURE);
|
---|
427 | }
|
---|
428 | }
|
---|
429 | else
|
---|
430 | {
|
---|
431 | sh_invalidnum (cmdarg);
|
---|
432 | return (EXECUTION_FAILURE);
|
---|
433 | }
|
---|
434 |
|
---|
435 | if (set_limit (limind, real_limit, mode) < 0)
|
---|
436 | {
|
---|
437 | builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
|
---|
438 | strerror (errno));
|
---|
439 | return (EXECUTION_FAILURE);
|
---|
440 | }
|
---|
441 |
|
---|
442 | return (EXECUTION_SUCCESS);
|
---|
443 | }
|
---|
444 |
|
---|
445 | static int
|
---|
446 | get_limit (ind, softlim, hardlim)
|
---|
447 | int ind;
|
---|
448 | RLIMTYPE *softlim, *hardlim;
|
---|
449 | {
|
---|
450 | RLIMTYPE value;
|
---|
451 | #if defined (HAVE_RESOURCE)
|
---|
452 | struct rlimit limit;
|
---|
453 | #endif
|
---|
454 |
|
---|
455 | if (limits[ind].parameter >= 256)
|
---|
456 | {
|
---|
457 | switch (limits[ind].parameter)
|
---|
458 | {
|
---|
459 | case RLIMIT_FILESIZE:
|
---|
460 | if (filesize (&value) < 0)
|
---|
461 | return -1;
|
---|
462 | break;
|
---|
463 | case RLIMIT_PIPESIZE:
|
---|
464 | if (pipesize (&value) < 0)
|
---|
465 | return -1;
|
---|
466 | break;
|
---|
467 | case RLIMIT_OPENFILES:
|
---|
468 | value = (RLIMTYPE)getdtablesize ();
|
---|
469 | break;
|
---|
470 | case RLIMIT_VIRTMEM:
|
---|
471 | return (getmaxvm (softlim, hardlim));
|
---|
472 | case RLIMIT_MAXUPROC:
|
---|
473 | if (getmaxuprc (&value) < 0)
|
---|
474 | return -1;
|
---|
475 | break;
|
---|
476 | default:
|
---|
477 | errno = EINVAL;
|
---|
478 | return -1;
|
---|
479 | }
|
---|
480 | *softlim = *hardlim = value;
|
---|
481 | return (0);
|
---|
482 | }
|
---|
483 | else
|
---|
484 | {
|
---|
485 | #if defined (HAVE_RESOURCE)
|
---|
486 | if (getrlimit (limits[ind].parameter, &limit) < 0)
|
---|
487 | return -1;
|
---|
488 | *softlim = limit.rlim_cur;
|
---|
489 | *hardlim = limit.rlim_max;
|
---|
490 | # if defined (HPUX9)
|
---|
491 | if (limits[ind].parameter == RLIMIT_FILESIZE)
|
---|
492 | {
|
---|
493 | *softlim *= 512;
|
---|
494 | *hardlim *= 512; /* Ugh. */
|
---|
495 | }
|
---|
496 | else
|
---|
497 | # endif /* HPUX9 */
|
---|
498 | return 0;
|
---|
499 | #else
|
---|
500 | errno = EINVAL;
|
---|
501 | return -1;
|
---|
502 | #endif
|
---|
503 | }
|
---|
504 | }
|
---|
505 |
|
---|
506 | static int
|
---|
507 | set_limit (ind, newlim, mode)
|
---|
508 | int ind;
|
---|
509 | RLIMTYPE newlim;
|
---|
510 | int mode;
|
---|
511 | {
|
---|
512 | #if defined (HAVE_RESOURCE)
|
---|
513 | struct rlimit limit;
|
---|
514 | RLIMTYPE val;
|
---|
515 | #endif
|
---|
516 |
|
---|
517 | if (limits[ind].parameter >= 256)
|
---|
518 | switch (limits[ind].parameter)
|
---|
519 | {
|
---|
520 | case RLIMIT_FILESIZE:
|
---|
521 | #if !defined (HAVE_RESOURCE)
|
---|
522 | return (ulimit (2, newlim / 512L));
|
---|
523 | #else
|
---|
524 | errno = EINVAL;
|
---|
525 | return -1;
|
---|
526 | #endif
|
---|
527 |
|
---|
528 | case RLIMIT_OPENFILES:
|
---|
529 | #if defined (HAVE_SETDTABLESIZE)
|
---|
530 | # if defined (__CYGWIN__)
|
---|
531 | /* Grrr... Cygwin declares setdtablesize as void. */
|
---|
532 | setdtablesize (newlim);
|
---|
533 | return 0;
|
---|
534 | # else
|
---|
535 | return (setdtablesize (newlim));
|
---|
536 | # endif
|
---|
537 | #endif
|
---|
538 | case RLIMIT_PIPESIZE:
|
---|
539 | case RLIMIT_VIRTMEM:
|
---|
540 | case RLIMIT_MAXUPROC:
|
---|
541 | default:
|
---|
542 | errno = EINVAL;
|
---|
543 | return -1;
|
---|
544 | }
|
---|
545 | else
|
---|
546 | {
|
---|
547 | #if defined (HAVE_RESOURCE)
|
---|
548 | if (getrlimit (limits[ind].parameter, &limit) < 0)
|
---|
549 | return -1;
|
---|
550 | # if defined (HPUX9)
|
---|
551 | if (limits[ind].parameter == RLIMIT_FILESIZE)
|
---|
552 | newlim /= 512; /* Ugh. */
|
---|
553 | # endif /* HPUX9 */
|
---|
554 | val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
|
---|
555 | (mode & LIMIT_HARD) == 0 && /* XXX -- test */
|
---|
556 | (limit.rlim_cur <= limit.rlim_max))
|
---|
557 | ? limit.rlim_max : newlim;
|
---|
558 | if (mode & LIMIT_SOFT)
|
---|
559 | limit.rlim_cur = val;
|
---|
560 | if (mode & LIMIT_HARD)
|
---|
561 | limit.rlim_max = val;
|
---|
562 |
|
---|
563 | return (setrlimit (limits[ind].parameter, &limit));
|
---|
564 | #else
|
---|
565 | errno = EINVAL;
|
---|
566 | return -1;
|
---|
567 | #endif
|
---|
568 | }
|
---|
569 | }
|
---|
570 |
|
---|
571 | static int
|
---|
572 | getmaxvm (softlim, hardlim)
|
---|
573 | RLIMTYPE *softlim, *hardlim;
|
---|
574 | {
|
---|
575 | #if defined (HAVE_RESOURCE)
|
---|
576 | struct rlimit datalim, stacklim;
|
---|
577 |
|
---|
578 | if (getrlimit (RLIMIT_DATA, &datalim) < 0)
|
---|
579 | return -1;
|
---|
580 |
|
---|
581 | if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
|
---|
582 | return -1;
|
---|
583 |
|
---|
584 | /* Protect against overflow. */
|
---|
585 | *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
|
---|
586 | *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
|
---|
587 | return 0;
|
---|
588 | #else
|
---|
589 | errno = EINVAL;
|
---|
590 | return -1;
|
---|
591 | #endif /* HAVE_RESOURCE */
|
---|
592 | }
|
---|
593 |
|
---|
594 | static int
|
---|
595 | filesize(valuep)
|
---|
596 | RLIMTYPE *valuep;
|
---|
597 | {
|
---|
598 | #if !defined (HAVE_RESOURCE)
|
---|
599 | long result;
|
---|
600 | if ((result = ulimit (1, 0L)) < 0)
|
---|
601 | return -1;
|
---|
602 | else
|
---|
603 | *valuep = (RLIMTYPE) result * 512;
|
---|
604 | return 0;
|
---|
605 | #else
|
---|
606 | errno = EINVAL;
|
---|
607 | return -1;
|
---|
608 | #endif
|
---|
609 | }
|
---|
610 |
|
---|
611 | static int
|
---|
612 | pipesize (valuep)
|
---|
613 | RLIMTYPE *valuep;
|
---|
614 | {
|
---|
615 | #if defined (PIPE_BUF)
|
---|
616 | /* This is defined on Posix systems. */
|
---|
617 | *valuep = (RLIMTYPE) PIPE_BUF;
|
---|
618 | return 0;
|
---|
619 | #else
|
---|
620 | # if defined (_POSIX_PIPE_BUF)
|
---|
621 | *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
|
---|
622 | return 0;
|
---|
623 | # else
|
---|
624 | # if defined (PIPESIZE)
|
---|
625 | /* This is defined by running a program from the Makefile. */
|
---|
626 | *valuep = (RLIMTYPE) PIPESIZE;
|
---|
627 | return 0;
|
---|
628 | # else
|
---|
629 | errno = EINVAL;
|
---|
630 | return -1;
|
---|
631 | # endif /* PIPESIZE */
|
---|
632 | # endif /* _POSIX_PIPE_BUF */
|
---|
633 | #endif /* PIPE_BUF */
|
---|
634 | }
|
---|
635 |
|
---|
636 | static int
|
---|
637 | getmaxuprc (valuep)
|
---|
638 | RLIMTYPE *valuep;
|
---|
639 | {
|
---|
640 | long maxchild;
|
---|
641 |
|
---|
642 | maxchild = getmaxchild ();
|
---|
643 | if (maxchild < 0)
|
---|
644 | {
|
---|
645 | errno = EINVAL;
|
---|
646 | return -1;
|
---|
647 | }
|
---|
648 | else
|
---|
649 | {
|
---|
650 | *valuep = (RLIMTYPE) maxchild;
|
---|
651 | return 0;
|
---|
652 | }
|
---|
653 | }
|
---|
654 |
|
---|
655 | static void
|
---|
656 | print_all_limits (mode)
|
---|
657 | int mode;
|
---|
658 | {
|
---|
659 | register int i;
|
---|
660 | RLIMTYPE softlim, hardlim;
|
---|
661 |
|
---|
662 | if (mode == 0)
|
---|
663 | mode |= LIMIT_SOFT;
|
---|
664 |
|
---|
665 | for (i = 0; limits[i].option > 0; i++)
|
---|
666 | {
|
---|
667 | if (get_limit (i, &softlim, &hardlim) == 0)
|
---|
668 | printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
|
---|
669 | else if (errno != EINVAL)
|
---|
670 | builtin_error ("%s: cannot get limit: %s", limits[i].description,
|
---|
671 | strerror (errno));
|
---|
672 | }
|
---|
673 | }
|
---|
674 |
|
---|
675 | static void
|
---|
676 | printone (limind, curlim, pdesc)
|
---|
677 | int limind;
|
---|
678 | RLIMTYPE curlim;
|
---|
679 | int pdesc;
|
---|
680 | {
|
---|
681 | char unitstr[64];
|
---|
682 |
|
---|
683 | if (pdesc)
|
---|
684 | {
|
---|
685 | if (limits[limind].units)
|
---|
686 | sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
|
---|
687 | else
|
---|
688 | sprintf (unitstr, "(-%c) ", limits[limind].option);
|
---|
689 |
|
---|
690 | printf ("%-20s %16s", limits[limind].description, unitstr);
|
---|
691 | }
|
---|
692 | if (curlim == RLIM_INFINITY)
|
---|
693 | puts ("unlimited");
|
---|
694 | else if (curlim == RLIM_SAVED_MAX)
|
---|
695 | puts ("hard");
|
---|
696 | else if (curlim == RLIM_SAVED_CUR)
|
---|
697 | puts ("soft");
|
---|
698 | else
|
---|
699 | print_rlimtype ((curlim / limits[limind].block_factor), 1);
|
---|
700 | }
|
---|
701 |
|
---|
702 | /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
|
---|
703 | causes all limits to be set as high as possible depending on mode (like
|
---|
704 | csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
|
---|
705 | were set successfully, and 1 if at least one limit could not be set.
|
---|
706 |
|
---|
707 | To raise all soft limits to their corresponding hard limits, use
|
---|
708 | ulimit -S -a unlimited
|
---|
709 | To attempt to raise all hard limits to infinity (superuser-only), use
|
---|
710 | ulimit -H -a unlimited
|
---|
711 | To attempt to raise all soft and hard limits to infinity, use
|
---|
712 | ulimit -a unlimited
|
---|
713 | */
|
---|
714 |
|
---|
715 | static int
|
---|
716 | set_all_limits (mode, newlim)
|
---|
717 | int mode;
|
---|
718 | RLIMTYPE newlim;
|
---|
719 | {
|
---|
720 | register int i;
|
---|
721 | int retval = 0;
|
---|
722 |
|
---|
723 | if (newlim != RLIM_INFINITY)
|
---|
724 | {
|
---|
725 | errno = EINVAL;
|
---|
726 | return -1;
|
---|
727 | }
|
---|
728 |
|
---|
729 | if (mode == 0)
|
---|
730 | mode = LIMIT_SOFT|LIMIT_HARD;
|
---|
731 |
|
---|
732 | for (retval = i = 0; limits[i].option > 0; i++)
|
---|
733 | if (set_limit (i, newlim, mode) < 0)
|
---|
734 | {
|
---|
735 | builtin_error ("%s: cannot modify limit: %s", limits[i].description,
|
---|
736 | strerror (errno));
|
---|
737 | retval = 1;
|
---|
738 | }
|
---|
739 | return retval;
|
---|
740 | }
|
---|
741 |
|
---|
742 | #endif /* !_MINIX */
|
---|