1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
4 Copyright (C) 1987-2003 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)
73 #include "../bashintl.h"
77 #include "bashgetopt.h"
84 /* For some reason, HPUX chose to make these definitions visible only if
85 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
86 and #undef it afterward. */
87 #if defined (HAVE_RESOURCE)
88 # include <sys/time.h>
89 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
92 # include <sys/resource.h>
93 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
97 # include <sys/times.h>
100 #if defined (HAVE_LIMITS_H)
104 /* Check for the most basic symbols. If they aren't present, this
105 system's <sys/resource.h> isn't very useful to us. */
106 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
107 # undef HAVE_RESOURCE
110 #if !defined (RLIMTYPE)
111 # define RLIMTYPE long
112 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
113 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
116 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
117 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
118 # define RLIMIT_NOFILE RLIMIT_OFILE
119 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
121 /* Some systems have these, some do not. */
123 # define RLIMIT_FILESIZE RLIMIT_FSIZE
125 # define RLIMIT_FILESIZE 256
128 #define RLIMIT_PIPESIZE 257
131 # define RLIMIT_OPENFILES RLIMIT_NOFILE
133 # define RLIMIT_OPENFILES 258
137 # define RLIMIT_VIRTMEM RLIMIT_VMEM
138 # define RLIMIT_VMBLKSZ 1024
141 # define RLIMIT_VIRTMEM RLIMIT_AS
142 # define RLIMIT_VMBLKSZ 1024
144 # define RLIMIT_VIRTMEM 259
145 # define RLIMIT_VMBLKSZ 1
150 # define RLIMIT_MAXUPROC RLIMIT_NPROC
152 # define RLIMIT_MAXUPROC 260
155 #if !defined (RLIM_INFINITY)
156 # define RLIM_INFINITY 0x7fffffff
159 #if !defined (RLIM_SAVED_CUR)
160 # define RLIM_SAVED_CUR RLIM_INFINITY
163 #if !defined (RLIM_SAVED_MAX)
164 # define RLIM_SAVED_MAX RLIM_INFINITY
167 #define LIMIT_HARD 0x01
168 #define LIMIT_SOFT 0x02
170 static int _findlim __P((int));
172 static int ulimit_internal __P((int, char *, int, int));
174 static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *));
175 static int set_limit __P((int, RLIMTYPE, int));
177 static void printone __P((int, RLIMTYPE, int));
178 static void print_all_limits __P((int));
180 static int set_all_limits __P((int, RLIMTYPE));
182 static int filesize __P((RLIMTYPE *));
183 static int pipesize __P((RLIMTYPE *));
184 static int getmaxuprc __P((RLIMTYPE *));
185 static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *));
188 int option; /* The ulimit option for this limit. */
189 int parameter; /* Parameter to pass to get_limit (). */
190 int block_factor; /* Blocking factor for specific limit. */
191 char *description; /* Descriptive string to output. */
192 char *units; /* scale */
195 static RESOURCE_LIMITS limits[] = {
197 { 'c', RLIMIT_CORE, 1024, "core file size", "blocks" },
200 { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
202 { 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
203 #ifdef RLIMIT_MEMLOCK
204 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
207 { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
208 #endif /* RLIMIT_RSS */
209 { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
210 { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
212 { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
215 { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
216 #endif /* RLIMIT_CPU */
217 { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
218 #if defined (HAVE_RESOURCE)
219 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
222 { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
224 { -1, -1, -1, (char *)NULL, (char *)NULL }
226 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
228 typedef struct _cmd {
233 static ULCMD *cmdlist;
235 static int cmdlistsz;
237 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
246 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
254 for (i = 0; limits[i].option > 0; i++)
255 if (limits[i].option == opt)
260 static char optstring[4 + 2 * NCMDS];
262 /* Report or set limits associated with certain per-process resources.
263 See the help documentation in builtins.c for a full description. */
265 ulimit_builtin (list)
266 register WORD_LIST *list;
269 int c, limind, mode, opt, all_limits;
275 /* Idea stolen from pdksh -- build option string the first time called. */
276 if (optstring[0] == 0)
279 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
280 for (c = 0; limits[c].option > 0; c++)
282 *s++ = limits[c].option;
288 /* Initialize the command list. */
290 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
293 reset_internal_getopt ();
294 while ((opt = internal_getopt (list, optstring)) != -1)
302 /* -S and -H are modifiers, not real options. */
316 if (ncmd >= cmdlistsz)
317 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
318 cmdlist[ncmd].cmd = opt;
319 cmdlist[ncmd++].arg = list_optarg;
328 if (list) /* setting */
330 if (STREQ (list->word->word, "unlimited") == 0)
332 builtin_error (_("%s: invalid limit argument"), list->word->word);
333 return (EXECUTION_FAILURE);
335 return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
338 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
339 return (EXECUTION_SUCCESS);
342 /* default is `ulimit -f' */
345 cmdlist[ncmd].cmd = 'f';
346 /* `ulimit something' is same as `ulimit -f something' */
347 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
352 /* verify each command in the list. */
353 for (c = 0; c < ncmd; c++)
355 limind = _findlim (cmdlist[c].cmd);
358 builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
363 for (c = 0; c < ncmd; c++)
364 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
365 return (EXECUTION_FAILURE);
367 return (EXECUTION_SUCCESS);
371 ulimit_internal (cmd, cmdarg, mode, multiple)
376 int opt, limind, setting;
378 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
380 setting = cmdarg != 0;
381 limind = _findlim (cmd);
383 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
384 opt = get_limit (limind, &soft_limit, &hard_limit);
387 builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
389 return (EXECUTION_FAILURE);
392 if (setting == 0) /* print the value of the specified limit */
394 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
395 return (EXECUTION_SUCCESS);
398 /* Setting the limit. */
399 if (STREQ (cmdarg, "hard"))
400 real_limit = hard_limit;
401 else if (STREQ (cmdarg, "soft"))
402 real_limit = soft_limit;
403 else if (STREQ (cmdarg, "unlimited"))
404 real_limit = RLIM_INFINITY;
405 else if (all_digits (cmdarg))
407 limit = string_to_rlimtype (cmdarg);
408 block_factor = limits[limind].block_factor;
409 real_limit = limit * block_factor;
411 if ((real_limit / block_factor) != limit)
413 sh_erange (cmdarg, "limit");
414 return (EXECUTION_FAILURE);
419 sh_invalidnum (cmdarg);
420 return (EXECUTION_FAILURE);
423 if (set_limit (limind, real_limit, mode) < 0)
425 builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
427 return (EXECUTION_FAILURE);
430 return (EXECUTION_SUCCESS);
434 get_limit (ind, softlim, hardlim)
436 RLIMTYPE *softlim, *hardlim;
439 #if defined (HAVE_RESOURCE)
443 if (limits[ind].parameter >= 256)
445 switch (limits[ind].parameter)
447 case RLIMIT_FILESIZE:
448 if (filesize (&value) < 0)
451 case RLIMIT_PIPESIZE:
452 if (pipesize (&value) < 0)
455 case RLIMIT_OPENFILES:
456 value = (RLIMTYPE)getdtablesize ();
459 return (getmaxvm (softlim, hardlim));
460 case RLIMIT_MAXUPROC:
461 if (getmaxuprc (&value) < 0)
468 *softlim = *hardlim = value;
473 #if defined (HAVE_RESOURCE)
474 if (getrlimit (limits[ind].parameter, &limit) < 0)
476 *softlim = limit.rlim_cur;
477 *hardlim = limit.rlim_max;
479 if (limits[ind].parameter == RLIMIT_FILESIZE)
482 *hardlim *= 512; /* Ugh. */
495 set_limit (ind, newlim, mode)
500 #if defined (HAVE_RESOURCE)
505 if (limits[ind].parameter >= 256)
506 switch (limits[ind].parameter)
508 case RLIMIT_FILESIZE:
509 #if !defined (HAVE_RESOURCE)
510 return (ulimit (2, newlim / 512L));
516 case RLIMIT_OPENFILES:
517 #if defined (HAVE_SETDTABLESIZE)
518 # if defined (__CYGWIN__)
519 /* Grrr... Cygwin declares setdtablesize as void. */
520 setdtablesize (newlim);
523 return (setdtablesize (newlim));
526 case RLIMIT_PIPESIZE:
528 case RLIMIT_MAXUPROC:
535 #if defined (HAVE_RESOURCE)
536 if (getrlimit (limits[ind].parameter, &limit) < 0)
539 if (limits[ind].parameter == RLIMIT_FILESIZE)
540 newlim /= 512; /* Ugh. */
542 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
543 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
544 (limit.rlim_cur <= limit.rlim_max))
545 ? limit.rlim_max : newlim;
546 if (mode & LIMIT_SOFT)
547 limit.rlim_cur = val;
548 if (mode & LIMIT_HARD)
549 limit.rlim_max = val;
551 return (setrlimit (limits[ind].parameter, &limit));
560 getmaxvm (softlim, hardlim)
561 RLIMTYPE *softlim, *hardlim;
563 #if defined (HAVE_RESOURCE)
564 struct rlimit datalim, stacklim;
566 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
569 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
572 /* Protect against overflow. */
573 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
574 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
579 #endif /* HAVE_RESOURCE */
586 #if !defined (HAVE_RESOURCE)
588 if ((result = ulimit (1, 0L)) < 0)
591 *valuep = (RLIMTYPE) result * 512;
603 #if defined (PIPE_BUF)
604 /* This is defined on Posix systems. */
605 *valuep = (RLIMTYPE) PIPE_BUF;
608 # if defined (PIPESIZE)
609 /* This is defined by running a program from the Makefile. */
610 *valuep = (RLIMTYPE) PIPESIZE;
615 # endif /* PIPESIZE */
616 #endif /* PIPE_BUF */
625 maxchild = getmaxchild ();
633 *valuep = (RLIMTYPE) maxchild;
639 print_all_limits (mode)
643 RLIMTYPE softlim, hardlim;
648 for (i = 0; limits[i].option > 0; i++)
650 if (get_limit (i, &softlim, &hardlim) < 0)
651 builtin_error ("%s: cannot get limit: %s", limits[i].description,
654 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
659 printone (limind, curlim, pdesc)
668 if (limits[limind].units)
669 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
671 sprintf (unitstr, "(-%c) ", limits[limind].option);
673 printf ("%-18s %16s", limits[limind].description, unitstr);
675 if (curlim == RLIM_INFINITY)
677 else if (curlim == RLIM_SAVED_MAX)
679 else if (curlim == RLIM_SAVED_CUR)
682 print_rlimtype ((curlim / limits[limind].block_factor), 1);
685 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
686 causes all limits to be set as high as possible depending on mode (like
687 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
688 were set successfully, and 1 if at least one limit could not be set.
690 To raise all soft limits to their corresponding hard limits, use
691 ulimit -S -a unlimited
692 To attempt to raise all hard limits to infinity (superuser-only), use
693 ulimit -H -a unlimited
694 To attempt to raise all soft and hard limits to infinity, use
699 set_all_limits (mode, newlim)
706 if (newlim != RLIM_INFINITY)
713 mode = LIMIT_SOFT|LIMIT_HARD;
715 for (retval = i = 0; limits[i].option > 0; i++)
716 if (set_limit (i, newlim, mode) < 0)
718 builtin_error ("%s: cannot modify limit: %s", limits[i].description,