1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
4 Copyright (C) 1987-2002 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
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
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
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.
25 $FUNCTION ulimit_builtin
27 $SHORT_DOC ulimit [-SHacdflmnpstuv] [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:
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 -l the maximum size a process may lock into memory
39 -m the maximum resident set size
40 -n the maximum number of open file descriptors
41 -p the pipe buffer size
42 -s the maximum stack size
43 -t the maximum amount of cpu time in seconds
44 -u the maximum number of user processes
45 -v the size of virtual memory
47 If LIMIT is given, it is the new value of the specified resource;
48 the special LIMIT values `soft', `hard', and `unlimited' stand for
49 the current soft limit, the current hard limit, and no limit, respectively.
50 Otherwise, the current value of the specified resource is printed.
51 If no option is given, then -f is assumed. Values are in 1024-byte
52 increments, except for -t, which is in seconds, -p, which is in
53 increments of 512 bytes, and -u, which is an unscaled number of
61 #include "../bashtypes.h"
63 # include <sys/param.h>
66 #if defined (HAVE_UNISTD_H)
75 #include "bashgetopt.h"
82 /* For some reason, HPUX chose to make these definitions visible only if
83 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
84 and #undef it afterward. */
85 #if defined (HAVE_RESOURCE)
86 # include <sys/time.h>
87 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
90 # include <sys/resource.h>
91 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
95 # include <sys/times.h>
98 #if defined (HAVE_LIMITS_H)
102 /* Check for the most basic symbols. If they aren't present, this
103 system's <sys/resource.h> isn't very useful to us. */
104 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
105 # undef HAVE_RESOURCE
108 #if !defined (RLIMTYPE)
109 # define RLIMTYPE long
110 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
111 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
114 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
115 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
116 # define RLIMIT_NOFILE RLIMIT_OFILE
117 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
119 /* Some systems have these, some do not. */
121 # define RLIMIT_FILESIZE RLIMIT_FSIZE
123 # define RLIMIT_FILESIZE 256
126 #define RLIMIT_PIPESIZE 257
129 # define RLIMIT_OPENFILES RLIMIT_NOFILE
131 # define RLIMIT_OPENFILES 258
135 # define RLIMIT_VIRTMEM RLIMIT_VMEM
136 # define RLIMIT_VMBLKSZ 1024
139 # define RLIMIT_VIRTMEM RLIMIT_AS
140 # define RLIMIT_VMBLKSZ 1024
142 # define RLIMIT_VIRTMEM 259
143 # define RLIMIT_VMBLKSZ 1
148 # define RLIMIT_MAXUPROC RLIMIT_NPROC
150 # define RLIMIT_MAXUPROC 260
153 #if !defined (RLIM_INFINITY)
154 # define RLIM_INFINITY 0x7fffffff
157 #if !defined (RLIM_SAVED_CUR)
158 # define RLIM_SAVED_CUR RLIM_INFINITY
161 #if !defined (RLIM_SAVED_MAX)
162 # define RLIM_SAVED_MAX RLIM_INFINITY
165 #define LIMIT_HARD 0x01
166 #define LIMIT_SOFT 0x02
168 static int _findlim __P((int));
170 static int ulimit_internal __P((int, char *, int, int));
172 static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
173 static int set_limit __P((int, RLIMTYPE, int));
175 static void printone __P((int, RLIMTYPE, int));
176 static void print_all_limits __P((int));
178 static int set_all_limits __P((int, RLIMTYPE));
180 static int filesize __P((RLIMTYPE *));
181 static int pipesize __P((RLIMTYPE *));
182 static int getmaxuprc __P((RLIMTYPE *));
183 static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
186 int option; /* The ulimit option for this limit. */
187 int parameter; /* Parameter to pass to get_limit (). */
188 int block_factor; /* Blocking factor for specific limit. */
189 char *description; /* Descriptive string to output. */
190 char *units; /* scale */
193 static RESOURCE_LIMITS limits[] = {
195 { 'c', RLIMIT_CORE, 1024, "core file size", "blocks" },
198 { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
200 { 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
201 #ifdef RLIMIT_MEMLOCK
202 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
205 { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
206 #endif /* RLIMIT_RSS */
207 { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
208 { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
210 { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
213 { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
214 #endif /* RLIMIT_CPU */
215 { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
216 #if defined (HAVE_RESOURCE)
217 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
220 { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
222 { -1, -1, -1, (char *)NULL, (char *)NULL }
224 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
226 typedef struct _cmd {
231 static ULCMD *cmdlist;
233 static int cmdlistsz;
235 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
244 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
252 for (i = 0; limits[i].option > 0; i++)
253 if (limits[i].option == opt)
258 static char optstring[4 + 2 * NCMDS];
260 /* Report or set limits associated with certain per-process resources.
261 See the help documentation in builtins.c for a full description. */
263 ulimit_builtin (list)
264 register WORD_LIST *list;
267 int c, limind, mode, opt, all_limits;
273 /* Idea stolen from pdksh -- build option string the first time called. */
274 if (optstring[0] == 0)
277 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
278 for (c = 0; limits[c].option > 0; c++)
280 *s++ = limits[c].option;
286 /* Initialize the command list. */
288 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
291 reset_internal_getopt ();
292 while ((opt = internal_getopt (list, optstring)) != -1)
300 /* -S and -H are modifiers, not real options. */
314 if (ncmd >= cmdlistsz)
315 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
316 cmdlist[ncmd].cmd = opt;
317 cmdlist[ncmd++].arg = list_optarg;
326 if (list) /* setting */
328 if (STREQ (list->word->word, "unlimited") == 0)
330 builtin_error ("%s: invalid limit argument", list->word->word);
331 return (EXECUTION_FAILURE);
333 return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
336 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
337 return (EXECUTION_SUCCESS);
340 /* default is `ulimit -f' */
343 cmdlist[ncmd].cmd = 'f';
344 /* `ulimit something' is same as `ulimit -f something' */
345 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
350 /* verify each command in the list. */
351 for (c = 0; c < ncmd; c++)
353 limind = _findlim (cmdlist[c].cmd);
356 builtin_error ("`%c': bad command", cmdlist[c].cmd);
361 for (c = 0; c < ncmd; c++)
362 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
363 return (EXECUTION_FAILURE);
365 return (EXECUTION_SUCCESS);
369 ulimit_internal (cmd, cmdarg, mode, multiple)
374 int opt, limind, setting;
376 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
378 setting = cmdarg != 0;
379 limind = _findlim (cmd);
381 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
382 opt = get_limit (limind, &soft_limit, &hard_limit);
385 builtin_error ("%s: cannot get limit: %s", limits[limind].description,
387 return (EXECUTION_FAILURE);
390 if (setting == 0) /* print the value of the specified limit */
392 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
393 return (EXECUTION_SUCCESS);
396 /* Setting the limit. */
397 if (STREQ (cmdarg, "hard"))
398 real_limit = hard_limit;
399 else if (STREQ (cmdarg, "soft"))
400 real_limit = soft_limit;
401 else if (STREQ (cmdarg, "unlimited"))
402 real_limit = RLIM_INFINITY;
403 else if (all_digits (cmdarg))
405 limit = string_to_rlimtype (cmdarg);
406 block_factor = limits[limind].block_factor;
407 real_limit = limit * block_factor;
409 if ((real_limit / block_factor) != limit)
411 sh_erange (cmdarg, "limit");
412 return (EXECUTION_FAILURE);
417 sh_invalidnum (cmdarg);
418 return (EXECUTION_FAILURE);
421 if (set_limit (limind, real_limit, mode) < 0)
423 builtin_error ("%s: cannot modify limit: %s", limits[limind].description,
425 return (EXECUTION_FAILURE);
428 return (EXECUTION_SUCCESS);
432 get_limit (ind, softlim, hardlim)
434 RLIMTYPE *softlim, *hardlim;
437 #if defined (HAVE_RESOURCE)
441 if (limits[ind].parameter >= 256)
443 switch (limits[ind].parameter)
445 case RLIMIT_FILESIZE:
446 if (filesize (&value) < 0)
449 case RLIMIT_PIPESIZE:
450 if (pipesize (&value) < 0)
453 case RLIMIT_OPENFILES:
454 value = (RLIMTYPE)getdtablesize ();
457 return (getmaxvm (softlim, hardlim));
458 case RLIMIT_MAXUPROC:
459 if (getmaxuprc (&value) < 0)
466 *softlim = *hardlim = value;
471 #if defined (HAVE_RESOURCE)
472 if (getrlimit (limits[ind].parameter, &limit) < 0)
474 *softlim = limit.rlim_cur;
475 *hardlim = limit.rlim_max;
477 if (limits[ind].parameter == RLIMIT_FILESIZE)
480 *hardlim *= 512; /* Ugh. */
493 set_limit (ind, newlim, mode)
498 #if defined (HAVE_RESOURCE)
503 if (limits[ind].parameter >= 256)
504 switch (limits[ind].parameter)
506 case RLIMIT_FILESIZE:
507 #if !defined (HAVE_RESOURCE)
508 return (ulimit (2, newlim / 512L));
514 case RLIMIT_OPENFILES:
515 #if defined (HAVE_SETDTABLESIZE)
516 # if defined (__CYGWIN__)
517 /* Grrr... Cygwin declares setdtablesize as void. */
518 setdtablesize (newlim);
521 return (setdtablesize (newlim));
524 case RLIMIT_PIPESIZE:
526 case RLIMIT_MAXUPROC:
533 #if defined (HAVE_RESOURCE)
534 if (getrlimit (limits[ind].parameter, &limit) < 0)
537 if (limits[ind].parameter == RLIMIT_FILESIZE)
538 newlim /= 512; /* Ugh. */
540 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
541 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
542 (limit.rlim_cur <= limit.rlim_max))
543 ? limit.rlim_max : newlim;
544 if (mode & LIMIT_SOFT)
545 limit.rlim_cur = val;
546 if (mode & LIMIT_HARD)
547 limit.rlim_max = val;
549 return (setrlimit (limits[ind].parameter, &limit));
558 getmaxvm (softlim, hardlim)
559 RLIMTYPE *softlim, *hardlim;
561 #if defined (HAVE_RESOURCE)
562 struct rlimit datalim, stacklim;
564 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
567 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
570 /* Protect against overflow. */
571 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
572 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
577 #endif /* HAVE_RESOURCE */
584 #if !defined (HAVE_RESOURCE)
586 if ((result = ulimit (1, 0L)) < 0)
589 *valuep = (RLIMTYPE) result * 512;
601 #if defined (PIPE_BUF)
602 /* This is defined on Posix systems. */
603 *valuep = (RLIMTYPE) PIPE_BUF;
606 # if defined (PIPESIZE)
607 /* This is defined by running a program from the Makefile. */
608 *valuep = (RLIMTYPE) PIPESIZE;
613 # endif /* PIPESIZE */
614 #endif /* PIPE_BUF */
623 maxchild = getmaxchild ();
631 *valuep = (RLIMTYPE) maxchild;
637 print_all_limits (mode)
641 RLIMTYPE softlim, hardlim;
646 for (i = 0; limits[i].option > 0; i++)
648 if (get_limit (i, &softlim, &hardlim) < 0)
649 builtin_error ("%s: cannot get limit: %s", limits[i].description,
652 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
657 printone (limind, curlim, pdesc)
666 if (limits[limind].units)
667 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
669 sprintf (unitstr, "(-%c) ", limits[limind].option);
671 printf ("%-18s %16s", limits[limind].description, unitstr);
673 if (curlim == RLIM_INFINITY)
675 else if (curlim == RLIM_SAVED_MAX)
677 else if (curlim == RLIM_SAVED_CUR)
680 print_rlimtype ((curlim / limits[limind].block_factor), 1);
683 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
684 causes all limits to be set as high as possible depending on mode (like
685 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
686 were set successfully, and 1 if at least one limit could not be set.
688 To raise all soft limits to their corresponding hard limits, use
689 ulimit -S -a unlimited
690 To attempt to raise all hard limits to infinity (superuser-only), use
691 ulimit -H -a unlimited
692 To attempt to raise all soft and hard limits to infinity, use
697 set_all_limits (mode, newlim)
704 if (newlim != RLIM_INFINITY)
711 mode = LIMIT_SOFT|LIMIT_HARD;
713 for (retval = i = 0; limits[i].option > 0; i++)
714 if (set_limit (i, newlim, mode) < 0)
716 builtin_error ("%s: cannot modify limit: %s", limits[i].description,