1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
4 Copyright (C) 1987, 1989, 1991 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 ("invalid limit argument: %s", 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 ("bad command: `%c'", 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 ("cannot get %s 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 builtin_error ("limit out of range: %s", cmdarg);
412 return (EXECUTION_FAILURE);
417 builtin_error ("bad non-numeric arg `%s'", cmdarg);
418 return (EXECUTION_FAILURE);
421 if (set_limit (limind, real_limit, mode) < 0)
423 builtin_error ("cannot modify %s 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 */
621 # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
623 maxchild = sysconf (_SC_CHILD_MAX);
627 *valuep = (RLIMTYPE) maxchild;
629 # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
630 # if defined (MAXUPRC)
631 *valuep = (RLIMTYPE) MAXUPRC;
636 # endif /* !MAXUPRC */
637 # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
641 print_all_limits (mode)
645 RLIMTYPE softlim, hardlim;
650 for (i = 0; limits[i].option > 0; i++)
652 if (get_limit (i, &softlim, &hardlim) < 0)
653 builtin_error ("cannot get %s limit: %s", limits[i].description, strerror (errno));
655 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
660 printone (limind, curlim, pdesc)
669 if (limits[limind].units)
670 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
672 sprintf (unitstr, "(-%c) ", limits[limind].option);
674 printf ("%-18s %16s", limits[limind].description, unitstr);
676 if (curlim == RLIM_INFINITY)
678 else if (curlim == RLIM_SAVED_MAX)
680 else if (curlim == RLIM_SAVED_CUR)
683 print_rlimtype ((curlim / limits[limind].block_factor), 1);
686 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
687 causes all limits to be set as high as possible depending on mode (like
688 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
689 were set successfully, and 1 if at least one limit could not be set.
691 To raise all soft limits to their corresponding hard limits, use
692 ulimit -S -a unlimited
693 To attempt to raise all hard limits to infinity (superuser-only), use
694 ulimit -H -a unlimited
695 To attempt to raise all soft and hard limits to infinity, use
700 set_all_limits (mode, newlim)
707 if (newlim != RLIM_INFINITY)
714 mode = LIMIT_SOFT|LIMIT_HARD;
716 for (retval = i = 0; limits[i].option > 0; i++)
717 if (set_limit (i, newlim, mode) < 0)
719 builtin_error ("cannot modify %s limit: %s", limits[i].description,