1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
4 Copyright (C) 1987-2009 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
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
24 $FUNCTION ulimit_builtin
26 $SHORT_DOC ulimit [-SHacdefilmnpqrstuvx] [limit]
27 Modify shell resource limits.
29 Provides control over the resources available to the shell and processes
30 it creates, on systems that allow such control.
33 -S use the `soft' resource limit
34 -H use the `hard' resource limit
35 -a all current limits are reported
36 -b the socket buffer size
37 -c the maximum size of core files created
38 -d the maximum size of a process's data segment
39 -e the maximum scheduling priority (`nice')
40 -f the maximum size of files written by the shell and its children
41 -i the maximum number of pending signals
42 -l the maximum size a process may lock into memory
43 -m the maximum resident set size
44 -n the maximum number of open file descriptors
45 -p the pipe buffer size
46 -q the maximum number of bytes in POSIX message queues
47 -r the maximum real-time scheduling priority
48 -s the maximum stack size
49 -t the maximum amount of cpu time in seconds
50 -u the maximum number of user processes
51 -v the size of virtual memory
52 -x the maximum number of file locks
54 If LIMIT is given, it is the new value of the specified resource; the
55 special LIMIT values `soft', `hard', and `unlimited' stand for the
56 current soft limit, the current hard limit, and no limit, respectively.
57 Otherwise, the current value of the specified resource is printed. If
58 no option is given, then -f is assumed.
60 Values are in 1024-byte increments, except for -t, which is in seconds,
61 -p, which is in increments of 512 bytes, and -u, which is an unscaled
65 Returns success unless an invalid option is supplied or an error occurs.
72 #include "../bashtypes.h"
74 # include <sys/param.h>
77 #if defined (HAVE_UNISTD_H)
84 #include "../bashintl.h"
88 #include "bashgetopt.h"
95 /* For some reason, HPUX chose to make these definitions visible only if
96 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
97 and #undef it afterward. */
98 #if defined (HAVE_RESOURCE)
99 # include <sys/time.h>
100 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
103 # include <sys/resource.h>
104 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
107 #elif defined (HAVE_SYS_TIMES_H)
108 # include <sys/times.h>
111 #if defined (HAVE_LIMITS_H)
115 /* Check for the most basic symbols. If they aren't present, this
116 system's <sys/resource.h> isn't very useful to us. */
117 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
118 # undef HAVE_RESOURCE
121 #if !defined (RLIMTYPE)
122 # define RLIMTYPE long
123 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
124 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
127 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
128 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
129 # define RLIMIT_NOFILE RLIMIT_OFILE
130 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
132 /* Some systems have these, some do not. */
134 # define RLIMIT_FILESIZE RLIMIT_FSIZE
136 # define RLIMIT_FILESIZE 256
139 #define RLIMIT_PIPESIZE 257
142 # define RLIMIT_OPENFILES RLIMIT_NOFILE
144 # define RLIMIT_OPENFILES 258
148 # define RLIMIT_VIRTMEM RLIMIT_VMEM
149 # define RLIMIT_VMBLKSZ 1024
152 # define RLIMIT_VIRTMEM RLIMIT_AS
153 # define RLIMIT_VMBLKSZ 1024
155 # define RLIMIT_VIRTMEM 259
156 # define RLIMIT_VMBLKSZ 1
161 # define RLIMIT_MAXUPROC RLIMIT_NPROC
163 # define RLIMIT_MAXUPROC 260
166 #if !defined (RLIM_INFINITY)
167 # define RLIM_INFINITY 0x7fffffff
170 #if !defined (RLIM_SAVED_CUR)
171 # define RLIM_SAVED_CUR RLIM_INFINITY
174 #if !defined (RLIM_SAVED_MAX)
175 # define RLIM_SAVED_MAX RLIM_INFINITY
178 #define LIMIT_HARD 0x01
179 #define LIMIT_SOFT 0x02
181 /* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes
185 #define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
187 extern int posixly_correct;
189 static int _findlim __P((int));
191 static int ulimit_internal __P((int, char *, int, int));
193 static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
194 static int set_limit __P((int, RLIMTYPE, int));
196 static void printone __P((int, RLIMTYPE, int));
197 static void print_all_limits __P((int));
199 static int set_all_limits __P((int, RLIMTYPE));
201 static int filesize __P((RLIMTYPE *));
202 static int pipesize __P((RLIMTYPE *));
203 static int getmaxuprc __P((RLIMTYPE *));
204 static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
207 int option; /* The ulimit option for this limit. */
208 int parameter; /* Parameter to pass to get_limit (). */
209 int block_factor; /* Blocking factor for specific limit. */
210 const char * const description; /* Descriptive string to output. */
211 const char * const units; /* scale */
214 static RESOURCE_LIMITS limits[] = {
215 #ifdef RLIMIT_PTHREAD
216 { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
219 { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
222 { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" },
225 { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
228 { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
230 { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" },
231 #ifdef RLIMIT_SIGPENDING
232 { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
234 #ifdef RLIMIT_MEMLOCK
235 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
238 { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
239 #endif /* RLIMIT_RSS */
240 { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
241 { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
242 #ifdef RLIMIT_MSGQUEUE
243 { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
246 { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
249 { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
252 { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
253 #endif /* RLIMIT_CPU */
254 { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
255 #if defined (HAVE_RESOURCE)
256 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
259 { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
262 { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
264 { -1, -1, -1, (char *)NULL, (char *)NULL }
266 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
268 typedef struct _cmd {
273 static ULCMD *cmdlist;
275 static int cmdlistsz;
277 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
286 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
294 for (i = 0; limits[i].option > 0; i++)
295 if (limits[i].option == opt)
300 static char optstring[4 + 2 * NCMDS];
302 /* Report or set limits associated with certain per-process resources.
303 See the help documentation in builtins.c for a full description. */
305 ulimit_builtin (list)
306 register WORD_LIST *list;
309 int c, limind, mode, opt, all_limits;
315 /* Idea stolen from pdksh -- build option string the first time called. */
316 if (optstring[0] == 0)
319 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
320 for (c = 0; limits[c].option > 0; c++)
322 *s++ = limits[c].option;
328 /* Initialize the command list. */
330 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
333 reset_internal_getopt ();
334 while ((opt = internal_getopt (list, optstring)) != -1)
342 /* -S and -H are modifiers, not real options. */
356 if (ncmd >= cmdlistsz)
357 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
358 cmdlist[ncmd].cmd = opt;
359 cmdlist[ncmd++].arg = list_optarg;
368 if (list) /* setting */
370 if (STREQ (list->word->word, "unlimited") == 0)
372 builtin_error (_("%s: invalid limit argument"), list->word->word);
373 return (EXECUTION_FAILURE);
375 return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
378 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
379 return (sh_chkwrite (EXECUTION_SUCCESS));
382 /* default is `ulimit -f' */
385 cmdlist[ncmd].cmd = 'f';
386 /* `ulimit something' is same as `ulimit -f something' */
387 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
392 /* verify each command in the list. */
393 for (c = 0; c < ncmd; c++)
395 limind = _findlim (cmdlist[c].cmd);
398 builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
403 for (c = 0; c < ncmd; c++)
404 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
405 return (EXECUTION_FAILURE);
407 return (EXECUTION_SUCCESS);
411 ulimit_internal (cmd, cmdarg, mode, multiple)
416 int opt, limind, setting;
418 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
420 setting = cmdarg != 0;
421 limind = _findlim (cmd);
423 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
424 opt = get_limit (limind, &soft_limit, &hard_limit);
427 builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
429 return (EXECUTION_FAILURE);
432 if (setting == 0) /* print the value of the specified limit */
434 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
435 return (EXECUTION_SUCCESS);
438 /* Setting the limit. */
439 if (STREQ (cmdarg, "hard"))
440 real_limit = hard_limit;
441 else if (STREQ (cmdarg, "soft"))
442 real_limit = soft_limit;
443 else if (STREQ (cmdarg, "unlimited"))
444 real_limit = RLIM_INFINITY;
445 else if (all_digits (cmdarg))
447 limit = string_to_rlimtype (cmdarg);
448 block_factor = BLOCKSIZE(limits[limind].block_factor);
449 real_limit = limit * block_factor;
451 if ((real_limit / block_factor) != limit)
453 sh_erange (cmdarg, _("limit"));
454 return (EXECUTION_FAILURE);
459 sh_invalidnum (cmdarg);
460 return (EXECUTION_FAILURE);
463 if (set_limit (limind, real_limit, mode) < 0)
465 builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
467 return (EXECUTION_FAILURE);
470 return (EXECUTION_SUCCESS);
474 get_limit (ind, softlim, hardlim)
476 RLIMTYPE *softlim, *hardlim;
479 #if defined (HAVE_RESOURCE)
483 if (limits[ind].parameter >= 256)
485 switch (limits[ind].parameter)
487 case RLIMIT_FILESIZE:
488 if (filesize (&value) < 0)
491 case RLIMIT_PIPESIZE:
492 if (pipesize (&value) < 0)
495 case RLIMIT_OPENFILES:
496 value = (RLIMTYPE)getdtablesize ();
499 return (getmaxvm (softlim, hardlim));
500 case RLIMIT_MAXUPROC:
501 if (getmaxuprc (&value) < 0)
508 *softlim = *hardlim = value;
513 #if defined (HAVE_RESOURCE)
514 if (getrlimit (limits[ind].parameter, &limit) < 0)
516 *softlim = limit.rlim_cur;
517 *hardlim = limit.rlim_max;
519 if (limits[ind].parameter == RLIMIT_FILESIZE)
522 *hardlim *= 512; /* Ugh. */
535 set_limit (ind, newlim, mode)
540 #if defined (HAVE_RESOURCE)
545 if (limits[ind].parameter >= 256)
546 switch (limits[ind].parameter)
548 case RLIMIT_FILESIZE:
549 #if !defined (HAVE_RESOURCE)
550 return (ulimit (2, newlim / 512L));
556 case RLIMIT_OPENFILES:
557 #if defined (HAVE_SETDTABLESIZE)
558 # if defined (__CYGWIN__)
559 /* Grrr... Cygwin declares setdtablesize as void. */
560 setdtablesize (newlim);
563 return (setdtablesize (newlim));
566 case RLIMIT_PIPESIZE:
568 case RLIMIT_MAXUPROC:
575 #if defined (HAVE_RESOURCE)
576 if (getrlimit (limits[ind].parameter, &limit) < 0)
579 if (limits[ind].parameter == RLIMIT_FILESIZE)
580 newlim /= 512; /* Ugh. */
582 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
583 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
584 (limit.rlim_cur <= limit.rlim_max))
585 ? limit.rlim_max : newlim;
586 if (mode & LIMIT_SOFT)
587 limit.rlim_cur = val;
588 if (mode & LIMIT_HARD)
589 limit.rlim_max = val;
591 return (setrlimit (limits[ind].parameter, &limit));
600 getmaxvm (softlim, hardlim)
601 RLIMTYPE *softlim, *hardlim;
603 #if defined (HAVE_RESOURCE)
604 struct rlimit datalim, stacklim;
606 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
609 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
612 /* Protect against overflow. */
613 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
614 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
619 #endif /* HAVE_RESOURCE */
626 #if !defined (HAVE_RESOURCE)
628 if ((result = ulimit (1, 0L)) < 0)
631 *valuep = (RLIMTYPE) result * 512;
643 #if defined (PIPE_BUF)
644 /* This is defined on Posix systems. */
645 *valuep = (RLIMTYPE) PIPE_BUF;
648 # if defined (_POSIX_PIPE_BUF)
649 *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
652 # if defined (PIPESIZE)
653 /* This is defined by running a program from the Makefile. */
654 *valuep = (RLIMTYPE) PIPESIZE;
659 # endif /* PIPESIZE */
660 # endif /* _POSIX_PIPE_BUF */
661 #endif /* PIPE_BUF */
670 maxchild = getmaxchild ();
678 *valuep = (RLIMTYPE) maxchild;
684 print_all_limits (mode)
688 RLIMTYPE softlim, hardlim;
693 for (i = 0; limits[i].option > 0; i++)
695 if (get_limit (i, &softlim, &hardlim) == 0)
696 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
697 else if (errno != EINVAL)
698 builtin_error ("%s: cannot get limit: %s", limits[i].description,
704 printone (limind, curlim, pdesc)
712 factor = BLOCKSIZE(limits[limind].block_factor);
715 if (limits[limind].units)
716 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
718 sprintf (unitstr, "(-%c) ", limits[limind].option);
720 printf ("%-20s %16s", limits[limind].description, unitstr);
722 if (curlim == RLIM_INFINITY)
724 else if (curlim == RLIM_SAVED_MAX)
726 else if (curlim == RLIM_SAVED_CUR)
729 print_rlimtype ((curlim / factor), 1);
732 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
733 causes all limits to be set as high as possible depending on mode (like
734 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
735 were set successfully, and 1 if at least one limit could not be set.
737 To raise all soft limits to their corresponding hard limits, use
738 ulimit -S -a unlimited
739 To attempt to raise all hard limits to infinity (superuser-only), use
740 ulimit -H -a unlimited
741 To attempt to raise all soft and hard limits to infinity, use
746 set_all_limits (mode, newlim)
753 if (newlim != RLIM_INFINITY)
760 mode = LIMIT_SOFT|LIMIT_HARD;
762 for (retval = i = 0; limits[i].option > 0; i++)
763 if (set_limit (i, newlim, mode) < 0)
765 builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,