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 1, 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, 675 Mass Ave, Cambridge, MA 02139, 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 Otherwise, the current value of the specified resource is printed.
49 If no option is given, then -f is assumed. Values are in 1024-byte
50 increments, except for -t, which is in seconds, -p, which is in
51 increments of 512 bytes, and -u, which is an unscaled number of
57 #include "../bashtypes.h"
58 #include <sys/param.h>
60 #if defined (HAVE_UNISTD_H)
69 #include "bashgetopt.h"
76 /* For some reason, HPUX chose to make these definitions visible only if
77 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
78 and #undef it afterward. */
79 #if defined (HAVE_RESOURCE)
80 # include <sys/time.h>
81 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
84 # include <sys/resource.h>
85 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
89 # include <sys/times.h>
92 #if defined (HAVE_LIMITS_H)
96 /* Check for the most basic symbols. If they aren't present, this
97 system's <sys/resource.h> isn't very useful to us. */
98 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
102 #if !defined (RLIMTYPE)
103 # define RLIMTYPE long
104 # define string_to_rlimtype string_to_long
105 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
108 #define DESCFMT "%-28s"
110 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
111 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
112 # define RLIMIT_NOFILE RLIMIT_OFILE
113 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
115 /* Some systems have these, some do not. */
117 # define RLIMIT_FILESIZE RLIMIT_FSIZE
119 # define RLIMIT_FILESIZE 256
122 #define RLIMIT_PIPESIZE 257
125 # define RLIMIT_OPENFILES RLIMIT_NOFILE
127 # define RLIMIT_OPENFILES 258
131 # define RLIMIT_VIRTMEM RLIMIT_VMEM
132 # define RLIMIT_VMBLKSZ 1024
135 # define RLIMIT_VIRTMEM RLIMIT_AS
136 # define RLIMIT_VMBLKSZ 1024
138 # define RLIMIT_VIRTMEM 259
139 # define RLIMIT_VMBLKSZ 1
144 # define RLIMIT_MAXUPROC RLIMIT_NPROC
146 # define RLIMIT_MAXUPROC 260
149 #if !defined (RLIM_INFINITY)
150 # define RLIM_INFINITY 0x7fffffff
153 #if !defined (RLIM_INVALID)
154 # define RLIM_INVALID (RLIMTYPE)-1
157 #define LIMIT_HARD 0x01
158 #define LIMIT_SOFT 0x02
160 static int ulimit_internal ();
161 static void printone ();
162 static void print_all_limits ();
164 static int get_limit ();
165 static int set_limit ();
167 static RLIMTYPE filesize ();
168 static RLIMTYPE pipesize ();
169 static RLIMTYPE getmaxuprc ();
170 static RLIMTYPE getmaxvm ();
173 int option; /* The ulimit option for this limit. */
174 int parameter; /* Parameter to pass to get_limit (). */
175 int block_factor; /* Blocking factor for specific limit. */
176 char *description; /* Descriptive string to output. */
179 static RESOURCE_LIMITS limits[] = {
181 { 'c', RLIMIT_CORE, 1024, "core file size (blocks)" },
184 { 'd', RLIMIT_DATA, 1024, "data seg size (kbytes)" },
186 { 'f', RLIMIT_FILESIZE, 1024, "file size (blocks)" },
187 #ifdef RLIMIT_MEMLOCK
188 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory (kbytes)" },
191 { 'm', RLIMIT_RSS, 1024, "max memory size (kbytes)" },
192 #endif /* RLIMIT_RSS */
193 { 'n', RLIMIT_OPENFILES, 1, "open files" },
194 { 'p', RLIMIT_PIPESIZE, 512, "pipe size (512 bytes)" },
196 { 's', RLIMIT_STACK, 1024, "stack size (kbytes)" },
199 { 't', RLIMIT_CPU, 1, "cpu time (seconds)" },
200 #endif /* RLIMIT_CPU */
201 { 'u', RLIMIT_MAXUPROC, 1, "max user processes" },
202 #if defined (HAVE_RESOURCE)
203 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory (kbytes)" },
205 { -1, -1, -1, (char *)NULL }
207 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
209 typedef struct _cmd {
214 static ULCMD *cmdlist;
216 static int cmdlistsz;
218 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
227 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
235 for (i = 0; limits[i].option > 0; i++)
236 if (limits[i].option == opt)
241 static char optstring[4 + 2 * NCMDS];
243 /* Report or set limits associated with certain per-process resources.
244 See the help documentation in builtins.c for a full description. */
246 ulimit_builtin (list)
247 register WORD_LIST *list;
250 int c, limind, mode, opt, all_limits;
256 /* Idea stolen from pdksh -- build option string the first time called. */
257 if (optstring[0] == 0)
260 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
261 for (c = 0; limits[c].option > 0; c++)
263 *s++ = limits[c].option;
269 /* Initialize the command list. */
271 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
274 reset_internal_getopt ();
275 while ((opt = internal_getopt (list, optstring)) != -1)
283 /* -S and -H are modifiers, not real options. */
297 if (ncmd >= cmdlistsz)
298 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
299 cmdlist[ncmd].cmd = opt;
300 cmdlist[ncmd++].arg = list_optarg;
308 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
309 return (EXECUTION_SUCCESS);
312 /* default is `ulimit -f' */
315 cmdlist[ncmd].cmd = 'f';
316 /* `ulimit something' is same as `ulimit -f something' */
317 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
322 /* verify each command in the list. */
323 for (c = 0; c < ncmd; c++)
325 limind = _findlim (cmdlist[c].cmd);
328 builtin_error ("bad command: `%c'", cmdlist[c].cmd);
333 for (c = 0; c < ncmd; c++)
334 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
335 return (EXECUTION_FAILURE);
337 return (EXECUTION_SUCCESS);
341 ulimit_internal (cmd, cmdarg, mode, multiple)
346 int opt, limind, setting;
348 RLIMTYPE current_limit, real_limit, limit;
350 limit = RLIM_INVALID;
351 setting = cmdarg != 0;
352 limind = _findlim (cmd);
354 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
355 opt = get_limit (limind, mode, ¤t_limit);
358 builtin_error ("cannot get limit: %s", strerror (errno));
359 return (EXECUTION_FAILURE);
362 if (setting == 0) /* print the value of the specified limit */
364 printone (limind, current_limit, multiple);
365 return (EXECUTION_SUCCESS);
368 /* Setting the limit. */
369 if (STREQ (cmdarg, "unlimited"))
370 limit = RLIM_INFINITY;
371 else if (all_digits (cmdarg))
372 limit = string_to_rlimtype (cmdarg);
375 builtin_error ("bad non-numeric arg `%s'", cmdarg);
376 return (EXECUTION_FAILURE);
379 block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor;
380 real_limit = limit * block_factor;
382 if (real_limit < 0 || (real_limit == 0 && limit != 0))
384 builtin_error ("limit out of range: %d", limit);
385 return (EXECUTION_FAILURE);
388 if (set_limit (limind, real_limit, mode) < 0)
390 builtin_error ("cannot modify limit: %s", strerror (errno));
391 return (EXECUTION_FAILURE);
393 return (EXECUTION_SUCCESS);
397 get_limit (ind, mode, limptr)
402 #if defined (HAVE_RESOURCE)
406 if (limits[ind].parameter >= 256)
408 switch (limits[ind].parameter)
410 case RLIMIT_FILESIZE:
413 case RLIMIT_PIPESIZE:
416 case RLIMIT_OPENFILES:
417 value = (RLIMTYPE)getdtablesize ();
420 value = getmaxvm (mode);
422 case RLIMIT_MAXUPROC:
423 value = getmaxuprc (mode);
430 return ((value == RLIM_INVALID) ? -1 : 0);
434 #if defined (HAVE_RESOURCE)
435 if (getrlimit (limits[ind].parameter, &limit) < 0)
437 value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max;
448 set_limit (ind, newlim, mode)
453 #if defined (HAVE_RESOURCE)
458 if (limits[ind].parameter >= 256)
459 switch (limits[ind].parameter)
461 case RLIMIT_FILESIZE:
462 #if !defined (HAVE_RESOURCE)
463 return (ulimit (2, newlim / 512L));
469 case RLIMIT_OPENFILES:
470 #if defined (HAVE_SETDTABLESIZE)
471 return (setdtablesize (newlim));
473 case RLIMIT_PIPESIZE:
475 case RLIMIT_MAXUPROC:
482 #if defined (HAVE_RESOURCE)
483 if (getrlimit (limits[ind].parameter, &limit) < 0)
485 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
486 (limit.rlim_cur <= limit.rlim_max))
487 ? limit.rlim_max : newlim;
488 if (mode & LIMIT_SOFT)
489 limit.rlim_cur = val;
490 if (mode & LIMIT_HARD)
491 limit.rlim_max = val;
493 return (setrlimit (limits[ind].parameter, &limit));
505 #if defined (HAVE_RESOURCE)
507 RLIMTYPE maxdata, maxstack;
509 if (getrlimit (RLIMIT_DATA, &rl) < 0)
510 return (RLIM_INVALID);
512 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
514 if (getrlimit (RLIMIT_STACK, &rl) < 0)
515 return (RLIM_INVALID);
517 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
519 /* Protect against overflow. */
520 return ((maxdata / 1024L) + (maxstack / 1024L));
524 #endif /* HAVE_RESOURCE */
530 #if !defined (HAVE_RESOURCE)
531 return ((RLIMTYPE)ulimit (1, 0L));
541 #if defined (PIPE_BUF)
542 /* This is defined on Posix systems. */
543 return ((RLIMTYPE) PIPE_BUF);
545 # if defined (PIPESIZE)
546 /* This is defined by running a program from the Makefile. */
547 return ((RLIMTYPE) PIPESIZE);
551 # endif /* PIPESIZE */
552 #endif /* PIPE_BUF */
559 # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
560 return ((RLIMTYPE)sysconf (_SC_CHILD_MAX));
561 # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
562 # if defined (MAXUPRC)
563 return ((RLIMTYPE)MAXUPRC);
567 # endif /* !MAXUPRC */
568 # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
572 print_all_limits (mode)
581 for (i = 0; limits[i].option > 0; i++)
583 if (get_limit (i, mode, &value) < 0)
584 value = RLIM_INVALID;
585 printone (i, value, 1);
590 printone (limind, curlim, pdesc)
596 printf (DESCFMT, limits[limind].description);
597 if (curlim == RLIM_INFINITY)
599 else if (curlim == RLIM_INVALID)
600 printf ("cannot get limit: %s\n", strerror (errno));
602 print_rlimtype ((curlim / limits[limind].block_factor), 1);