1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
4 Copyright (C) 1987-2010 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 (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H)
125 #if !defined (RLIMTYPE)
126 # define RLIMTYPE long
127 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
128 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
131 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
132 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
133 # define RLIMIT_NOFILE RLIMIT_OFILE
134 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
136 /* Some systems have these, some do not. */
138 # define RLIMIT_FILESIZE RLIMIT_FSIZE
140 # define RLIMIT_FILESIZE 256
143 #define RLIMIT_PIPESIZE 257
146 # define RLIMIT_OPENFILES RLIMIT_NOFILE
148 # define RLIMIT_OPENFILES 258
152 # define RLIMIT_VIRTMEM RLIMIT_VMEM
153 # define RLIMIT_VMBLKSZ 1024
156 # define RLIMIT_VIRTMEM RLIMIT_AS
157 # define RLIMIT_VMBLKSZ 1024
159 # define RLIMIT_VIRTMEM 259
160 # define RLIMIT_VMBLKSZ 1
165 # define RLIMIT_MAXUPROC RLIMIT_NPROC
167 # define RLIMIT_MAXUPROC 260
170 #if !defined (RLIM_INFINITY)
171 # define RLIM_INFINITY 0x7fffffff
174 #if !defined (RLIM_SAVED_CUR)
175 # define RLIM_SAVED_CUR RLIM_INFINITY
178 #if !defined (RLIM_SAVED_MAX)
179 # define RLIM_SAVED_MAX RLIM_INFINITY
182 #define LIMIT_HARD 0x01
183 #define LIMIT_SOFT 0x02
185 /* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes
189 #define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
191 extern int posixly_correct;
193 static int _findlim __P((int));
195 static int ulimit_internal __P((int, char *, int, int));
197 static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
198 static int set_limit __P((int, RLIMTYPE, int));
200 static void printone __P((int, RLIMTYPE, int));
201 static void print_all_limits __P((int));
203 static int set_all_limits __P((int, RLIMTYPE));
205 static int filesize __P((RLIMTYPE *));
206 static int pipesize __P((RLIMTYPE *));
207 static int getmaxuprc __P((RLIMTYPE *));
208 static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
211 int option; /* The ulimit option for this limit. */
212 int parameter; /* Parameter to pass to get_limit (). */
213 int block_factor; /* Blocking factor for specific limit. */
214 const char * const description; /* Descriptive string to output. */
215 const char * const units; /* scale */
218 static RESOURCE_LIMITS limits[] = {
219 #ifdef RLIMIT_PTHREAD
220 { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
223 { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
226 { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" },
229 { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
232 { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
234 { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" },
235 #ifdef RLIMIT_SIGPENDING
236 { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
238 #ifdef RLIMIT_MEMLOCK
239 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
242 { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
243 #endif /* RLIMIT_RSS */
244 { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
245 { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
246 #ifdef RLIMIT_MSGQUEUE
247 { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
250 { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
253 { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
256 { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
257 #endif /* RLIMIT_CPU */
258 { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
259 #if defined (HAVE_RESOURCE)
260 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
263 { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
266 { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
268 { -1, -1, -1, (char *)NULL, (char *)NULL }
270 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
272 typedef struct _cmd {
277 static ULCMD *cmdlist;
279 static int cmdlistsz;
281 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
290 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
298 for (i = 0; limits[i].option > 0; i++)
299 if (limits[i].option == opt)
304 static char optstring[4 + 2 * NCMDS];
306 /* Report or set limits associated with certain per-process resources.
307 See the help documentation in builtins.c for a full description. */
309 ulimit_builtin (list)
310 register WORD_LIST *list;
313 int c, limind, mode, opt, all_limits;
319 /* Idea stolen from pdksh -- build option string the first time called. */
320 if (optstring[0] == 0)
323 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
324 for (c = 0; limits[c].option > 0; c++)
326 *s++ = limits[c].option;
332 /* Initialize the command list. */
334 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
337 reset_internal_getopt ();
338 while ((opt = internal_getopt (list, optstring)) != -1)
346 /* -S and -H are modifiers, not real options. */
360 if (ncmd >= cmdlistsz)
361 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
362 cmdlist[ncmd].cmd = opt;
363 cmdlist[ncmd++].arg = list_optarg;
372 if (list) /* setting */
374 if (STREQ (list->word->word, "unlimited") == 0)
376 builtin_error (_("%s: invalid limit argument"), list->word->word);
377 return (EXECUTION_FAILURE);
379 return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
382 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
383 return (sh_chkwrite (EXECUTION_SUCCESS));
386 /* default is `ulimit -f' */
389 cmdlist[ncmd].cmd = 'f';
390 /* `ulimit something' is same as `ulimit -f something' */
391 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
396 /* verify each command in the list. */
397 for (c = 0; c < ncmd; c++)
399 limind = _findlim (cmdlist[c].cmd);
402 builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
407 for (c = 0; c < ncmd; c++)
408 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
409 return (EXECUTION_FAILURE);
411 return (EXECUTION_SUCCESS);
415 ulimit_internal (cmd, cmdarg, mode, multiple)
420 int opt, limind, setting;
422 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
424 setting = cmdarg != 0;
425 limind = _findlim (cmd);
427 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
428 opt = get_limit (limind, &soft_limit, &hard_limit);
431 builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
433 return (EXECUTION_FAILURE);
436 if (setting == 0) /* print the value of the specified limit */
438 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
439 return (EXECUTION_SUCCESS);
442 /* Setting the limit. */
443 if (STREQ (cmdarg, "hard"))
444 real_limit = hard_limit;
445 else if (STREQ (cmdarg, "soft"))
446 real_limit = soft_limit;
447 else if (STREQ (cmdarg, "unlimited"))
448 real_limit = RLIM_INFINITY;
449 else if (all_digits (cmdarg))
451 limit = string_to_rlimtype (cmdarg);
452 block_factor = BLOCKSIZE(limits[limind].block_factor);
453 real_limit = limit * block_factor;
455 if ((real_limit / block_factor) != limit)
457 sh_erange (cmdarg, _("limit"));
458 return (EXECUTION_FAILURE);
463 sh_invalidnum (cmdarg);
464 return (EXECUTION_FAILURE);
467 if (set_limit (limind, real_limit, mode) < 0)
469 builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
471 return (EXECUTION_FAILURE);
474 return (EXECUTION_SUCCESS);
478 get_limit (ind, softlim, hardlim)
480 RLIMTYPE *softlim, *hardlim;
483 #if defined (HAVE_RESOURCE)
487 if (limits[ind].parameter >= 256)
489 switch (limits[ind].parameter)
491 case RLIMIT_FILESIZE:
492 if (filesize (&value) < 0)
495 case RLIMIT_PIPESIZE:
496 if (pipesize (&value) < 0)
499 case RLIMIT_OPENFILES:
500 value = (RLIMTYPE)getdtablesize ();
503 return (getmaxvm (softlim, hardlim));
504 case RLIMIT_MAXUPROC:
505 if (getmaxuprc (&value) < 0)
512 *softlim = *hardlim = value;
517 #if defined (HAVE_RESOURCE)
518 if (getrlimit (limits[ind].parameter, &limit) < 0)
520 *softlim = limit.rlim_cur;
521 *hardlim = limit.rlim_max;
523 if (limits[ind].parameter == RLIMIT_FILESIZE)
526 *hardlim *= 512; /* Ugh. */
539 set_limit (ind, newlim, mode)
544 #if defined (HAVE_RESOURCE)
549 if (limits[ind].parameter >= 256)
550 switch (limits[ind].parameter)
552 case RLIMIT_FILESIZE:
553 #if !defined (HAVE_RESOURCE)
554 return (ulimit (2, newlim / 512L));
560 case RLIMIT_OPENFILES:
561 #if defined (HAVE_SETDTABLESIZE)
562 # if defined (__CYGWIN__)
563 /* Grrr... Cygwin declares setdtablesize as void. */
564 setdtablesize (newlim);
567 return (setdtablesize (newlim));
570 case RLIMIT_PIPESIZE:
572 case RLIMIT_MAXUPROC:
579 #if defined (HAVE_RESOURCE)
580 if (getrlimit (limits[ind].parameter, &limit) < 0)
583 if (limits[ind].parameter == RLIMIT_FILESIZE)
584 newlim /= 512; /* Ugh. */
586 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
587 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
588 (limit.rlim_cur <= limit.rlim_max))
589 ? limit.rlim_max : newlim;
590 if (mode & LIMIT_SOFT)
591 limit.rlim_cur = val;
592 if (mode & LIMIT_HARD)
593 limit.rlim_max = val;
595 return (setrlimit (limits[ind].parameter, &limit));
604 getmaxvm (softlim, hardlim)
605 RLIMTYPE *softlim, *hardlim;
607 #if defined (HAVE_RESOURCE)
608 struct rlimit datalim, stacklim;
610 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
613 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
616 /* Protect against overflow. */
617 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
618 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
623 #endif /* HAVE_RESOURCE */
630 #if !defined (HAVE_RESOURCE)
632 if ((result = ulimit (1, 0L)) < 0)
635 *valuep = (RLIMTYPE) result * 512;
647 #if defined (PIPE_BUF)
648 /* This is defined on Posix systems. */
649 *valuep = (RLIMTYPE) PIPE_BUF;
652 # if defined (_POSIX_PIPE_BUF)
653 *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
656 # if defined (PIPESIZE)
657 /* This is defined by running a program from the Makefile. */
658 *valuep = (RLIMTYPE) PIPESIZE;
663 # endif /* PIPESIZE */
664 # endif /* _POSIX_PIPE_BUF */
665 #endif /* PIPE_BUF */
674 maxchild = getmaxchild ();
682 *valuep = (RLIMTYPE) maxchild;
688 print_all_limits (mode)
692 RLIMTYPE softlim, hardlim;
697 for (i = 0; limits[i].option > 0; i++)
699 if (get_limit (i, &softlim, &hardlim) == 0)
700 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
701 else if (errno != EINVAL)
702 builtin_error ("%s: cannot get limit: %s", limits[i].description,
708 printone (limind, curlim, pdesc)
716 factor = BLOCKSIZE(limits[limind].block_factor);
719 if (limits[limind].units)
720 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
722 sprintf (unitstr, "(-%c) ", limits[limind].option);
724 printf ("%-20s %16s", limits[limind].description, unitstr);
726 if (curlim == RLIM_INFINITY)
728 else if (curlim == RLIM_SAVED_MAX)
730 else if (curlim == RLIM_SAVED_CUR)
733 print_rlimtype ((curlim / factor), 1);
736 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
737 causes all limits to be set as high as possible depending on mode (like
738 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
739 were set successfully, and 1 if at least one limit could not be set.
741 To raise all soft limits to their corresponding hard limits, use
742 ulimit -S -a unlimited
743 To attempt to raise all hard limits to infinity (superuser-only), use
744 ulimit -H -a unlimited
745 To attempt to raise all soft and hard limits to infinity, use
750 set_all_limits (mode, newlim)
757 if (newlim != RLIM_INFINITY)
764 mode = LIMIT_SOFT|LIMIT_HARD;
766 for (retval = i = 0; limits[i].option > 0; i++)
767 if (set_limit (i, newlim, mode) < 0)
769 builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,