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
59 #include "../bashtypes.h"
61 # include <sys/param.h>
64 #if defined (HAVE_UNISTD_H)
73 #include "bashgetopt.h"
80 /* For some reason, HPUX chose to make these definitions visible only if
81 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
82 and #undef it afterward. */
83 #if defined (HAVE_RESOURCE)
84 # include <sys/time.h>
85 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
88 # include <sys/resource.h>
89 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
93 # include <sys/times.h>
96 #if defined (HAVE_LIMITS_H)
100 /* Check for the most basic symbols. If they aren't present, this
101 system's <sys/resource.h> isn't very useful to us. */
102 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
103 # undef HAVE_RESOURCE
106 #if !defined (RLIMTYPE)
107 # define RLIMTYPE long
108 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
109 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
112 #define DESCFMT "%-28s"
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_INVALID)
158 # define RLIM_INVALID (RLIMTYPE)-1
161 #define LIMIT_HARD 0x01
162 #define LIMIT_SOFT 0x02
164 static int ulimit_internal ();
165 static void printone ();
166 static void print_all_limits ();
168 static int get_limit ();
169 static int set_limit ();
171 static RLIMTYPE filesize ();
172 static RLIMTYPE pipesize ();
173 static RLIMTYPE getmaxuprc ();
174 static RLIMTYPE getmaxvm ();
177 int option; /* The ulimit option for this limit. */
178 int parameter; /* Parameter to pass to get_limit (). */
179 int block_factor; /* Blocking factor for specific limit. */
180 char *description; /* Descriptive string to output. */
183 static RESOURCE_LIMITS limits[] = {
185 { 'c', RLIMIT_CORE, 1024, "core file size (blocks)" },
188 { 'd', RLIMIT_DATA, 1024, "data seg size (kbytes)" },
190 { 'f', RLIMIT_FILESIZE, 1024, "file size (blocks)" },
191 #ifdef RLIMIT_MEMLOCK
192 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory (kbytes)" },
195 { 'm', RLIMIT_RSS, 1024, "max memory size (kbytes)" },
196 #endif /* RLIMIT_RSS */
197 { 'n', RLIMIT_OPENFILES, 1, "open files" },
198 { 'p', RLIMIT_PIPESIZE, 512, "pipe size (512 bytes)" },
200 { 's', RLIMIT_STACK, 1024, "stack size (kbytes)" },
203 { 't', RLIMIT_CPU, 1, "cpu time (seconds)" },
204 #endif /* RLIMIT_CPU */
205 { 'u', RLIMIT_MAXUPROC, 1, "max user processes" },
206 #if defined (HAVE_RESOURCE)
207 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory (kbytes)" },
209 { -1, -1, -1, (char *)NULL }
211 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
213 typedef struct _cmd {
218 static ULCMD *cmdlist;
220 static int cmdlistsz;
222 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
231 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
239 for (i = 0; limits[i].option > 0; i++)
240 if (limits[i].option == opt)
245 static char optstring[4 + 2 * NCMDS];
247 /* Report or set limits associated with certain per-process resources.
248 See the help documentation in builtins.c for a full description. */
250 ulimit_builtin (list)
251 register WORD_LIST *list;
254 int c, limind, mode, opt, all_limits;
260 /* Idea stolen from pdksh -- build option string the first time called. */
261 if (optstring[0] == 0)
264 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
265 for (c = 0; limits[c].option > 0; c++)
267 *s++ = limits[c].option;
273 /* Initialize the command list. */
275 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
278 reset_internal_getopt ();
279 while ((opt = internal_getopt (list, optstring)) != -1)
287 /* -S and -H are modifiers, not real options. */
301 if (ncmd >= cmdlistsz)
302 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
303 cmdlist[ncmd].cmd = opt;
304 cmdlist[ncmd++].arg = list_optarg;
312 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
313 return (EXECUTION_SUCCESS);
316 /* default is `ulimit -f' */
319 cmdlist[ncmd].cmd = 'f';
320 /* `ulimit something' is same as `ulimit -f something' */
321 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
326 /* verify each command in the list. */
327 for (c = 0; c < ncmd; c++)
329 limind = _findlim (cmdlist[c].cmd);
332 builtin_error ("bad command: `%c'", cmdlist[c].cmd);
337 for (c = 0; c < ncmd; c++)
338 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
339 return (EXECUTION_FAILURE);
341 return (EXECUTION_SUCCESS);
345 ulimit_internal (cmd, cmdarg, mode, multiple)
350 int opt, limind, setting;
352 RLIMTYPE current_limit, real_limit, limit;
354 limit = RLIM_INVALID;
355 setting = cmdarg != 0;
356 limind = _findlim (cmd);
358 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
359 opt = get_limit (limind, mode, ¤t_limit);
362 builtin_error ("cannot get limit: %s", strerror (errno));
363 return (EXECUTION_FAILURE);
366 if (setting == 0) /* print the value of the specified limit */
368 printone (limind, current_limit, multiple);
369 return (EXECUTION_SUCCESS);
372 /* Setting the limit. */
373 if (STREQ (cmdarg, "unlimited"))
374 limit = RLIM_INFINITY;
375 else if (all_digits (cmdarg))
376 limit = string_to_rlimtype (cmdarg);
379 builtin_error ("bad non-numeric arg `%s'", cmdarg);
380 return (EXECUTION_FAILURE);
383 block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor;
384 real_limit = limit * block_factor;
386 if (real_limit < 0 || (real_limit == 0 && limit != 0))
388 builtin_error ("limit out of range: %d", limit);
389 return (EXECUTION_FAILURE);
392 if (set_limit (limind, real_limit, mode) < 0)
394 builtin_error ("cannot modify limit: %s", strerror (errno));
395 return (EXECUTION_FAILURE);
397 return (EXECUTION_SUCCESS);
401 get_limit (ind, mode, limptr)
406 #if defined (HAVE_RESOURCE)
410 if (limits[ind].parameter >= 256)
412 switch (limits[ind].parameter)
414 case RLIMIT_FILESIZE:
417 case RLIMIT_PIPESIZE:
420 case RLIMIT_OPENFILES:
421 value = (RLIMTYPE)getdtablesize ();
424 value = getmaxvm (mode);
426 case RLIMIT_MAXUPROC:
427 value = getmaxuprc (mode);
434 return ((value == RLIM_INVALID) ? -1 : 0);
438 #if defined (HAVE_RESOURCE)
439 if (getrlimit (limits[ind].parameter, &limit) < 0)
441 value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max;
452 set_limit (ind, newlim, mode)
457 #if defined (HAVE_RESOURCE)
462 if (limits[ind].parameter >= 256)
463 switch (limits[ind].parameter)
465 case RLIMIT_FILESIZE:
466 #if !defined (HAVE_RESOURCE)
467 return (ulimit (2, newlim / 512L));
473 case RLIMIT_OPENFILES:
474 #if defined (HAVE_SETDTABLESIZE)
475 return (setdtablesize (newlim));
477 case RLIMIT_PIPESIZE:
479 case RLIMIT_MAXUPROC:
486 #if defined (HAVE_RESOURCE)
487 if (getrlimit (limits[ind].parameter, &limit) < 0)
489 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
490 (limit.rlim_cur <= limit.rlim_max))
491 ? limit.rlim_max : newlim;
492 if (mode & LIMIT_SOFT)
493 limit.rlim_cur = val;
494 if (mode & LIMIT_HARD)
495 limit.rlim_max = val;
497 return (setrlimit (limits[ind].parameter, &limit));
509 #if defined (HAVE_RESOURCE)
511 RLIMTYPE maxdata, maxstack;
513 if (getrlimit (RLIMIT_DATA, &rl) < 0)
514 return (RLIM_INVALID);
516 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
518 if (getrlimit (RLIMIT_STACK, &rl) < 0)
519 return (RLIM_INVALID);
521 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
523 /* Protect against overflow. */
524 return ((maxdata / 1024L) + (maxstack / 1024L));
528 #endif /* HAVE_RESOURCE */
534 #if !defined (HAVE_RESOURCE)
535 return ((RLIMTYPE)ulimit (1, 0L));
545 #if defined (PIPE_BUF)
546 /* This is defined on Posix systems. */
547 return ((RLIMTYPE) PIPE_BUF);
549 # if defined (PIPESIZE)
550 /* This is defined by running a program from the Makefile. */
551 return ((RLIMTYPE) PIPESIZE);
555 # endif /* PIPESIZE */
556 #endif /* PIPE_BUF */
563 # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
564 return ((RLIMTYPE)sysconf (_SC_CHILD_MAX));
565 # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
566 # if defined (MAXUPRC)
567 return ((RLIMTYPE)MAXUPRC);
571 # endif /* !MAXUPRC */
572 # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
576 print_all_limits (mode)
585 for (i = 0; limits[i].option > 0; i++)
587 if (get_limit (i, mode, &value) < 0)
588 value = RLIM_INVALID;
589 printone (i, value, 1);
594 printone (limind, curlim, pdesc)
600 printf (DESCFMT, limits[limind].description);
601 if (curlim == RLIM_INFINITY)
603 else if (curlim == RLIM_INVALID)
604 builtin_error ("cannot get limit: %s\n", strerror (errno));
606 print_rlimtype ((curlim / limits[limind].block_factor), 1);