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 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 #define LIMIT_HARD 0x01
158 #define LIMIT_SOFT 0x02
160 static int ulimit_internal __P((int, char *, int, int));
161 static void printone __P((int, RLIMTYPE, int));
162 static void print_all_limits __P((int));
164 static int get_limit __P((int, int, RLIMTYPE *));
165 static int set_limit __P((int, RLIMTYPE, int));
167 static int filesize __P((RLIMTYPE *));
168 static int pipesize __P((RLIMTYPE *));
169 static int getmaxuprc __P((int, RLIMTYPE *));
170 static int getmaxvm __P((int, RLIMTYPE *));
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)" },
206 { 'w', RLIMIT_SWAP, 1024, "swap size (kbytes)" },
208 { -1, -1, -1, (char *)NULL }
210 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
212 typedef struct _cmd {
217 static ULCMD *cmdlist;
219 static int cmdlistsz;
221 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
230 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
238 for (i = 0; limits[i].option > 0; i++)
239 if (limits[i].option == opt)
244 static char optstring[4 + 2 * NCMDS];
246 /* Report or set limits associated with certain per-process resources.
247 See the help documentation in builtins.c for a full description. */
249 ulimit_builtin (list)
250 register WORD_LIST *list;
253 int c, limind, mode, opt, all_limits;
259 /* Idea stolen from pdksh -- build option string the first time called. */
260 if (optstring[0] == 0)
263 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
264 for (c = 0; limits[c].option > 0; c++)
266 *s++ = limits[c].option;
272 /* Initialize the command list. */
274 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
277 reset_internal_getopt ();
278 while ((opt = internal_getopt (list, optstring)) != -1)
286 /* -S and -H are modifiers, not real options. */
300 if (ncmd >= cmdlistsz)
301 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
302 cmdlist[ncmd].cmd = opt;
303 cmdlist[ncmd++].arg = list_optarg;
311 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
312 return (EXECUTION_SUCCESS);
315 /* default is `ulimit -f' */
318 cmdlist[ncmd].cmd = 'f';
319 /* `ulimit something' is same as `ulimit -f something' */
320 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
325 /* verify each command in the list. */
326 for (c = 0; c < ncmd; c++)
328 limind = _findlim (cmdlist[c].cmd);
331 builtin_error ("bad command: `%c'", cmdlist[c].cmd);
336 for (c = 0; c < ncmd; c++)
337 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
338 return (EXECUTION_FAILURE);
340 return (EXECUTION_SUCCESS);
344 ulimit_internal (cmd, cmdarg, mode, multiple)
349 int opt, limind, setting;
351 RLIMTYPE current_limit, real_limit, limit;
353 setting = cmdarg != 0;
354 limind = _findlim (cmd);
356 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
357 opt = get_limit (limind, mode, ¤t_limit);
360 builtin_error ("cannot get limit: %s", strerror (errno));
361 return (EXECUTION_FAILURE);
364 if (setting == 0) /* print the value of the specified limit */
366 printone (limind, current_limit, multiple);
367 return (EXECUTION_SUCCESS);
370 /* Setting the limit. */
371 if (STREQ (cmdarg, "unlimited"))
372 limit = RLIM_INFINITY;
373 else if (all_digits (cmdarg))
374 limit = string_to_rlimtype (cmdarg);
377 builtin_error ("bad non-numeric arg `%s'", cmdarg);
378 return (EXECUTION_FAILURE);
381 block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor;
382 real_limit = limit * block_factor;
384 if (real_limit < 0 || (real_limit == 0 && limit != 0))
386 builtin_error ("limit out of range: %d", limit);
387 return (EXECUTION_FAILURE);
390 if (set_limit (limind, real_limit, mode) < 0)
392 builtin_error ("cannot modify limit: %s", strerror (errno));
393 return (EXECUTION_FAILURE);
395 return (EXECUTION_SUCCESS);
399 get_limit (ind, mode, limptr)
404 #if defined (HAVE_RESOURCE)
408 if (limits[ind].parameter >= 256)
410 switch (limits[ind].parameter)
412 case RLIMIT_FILESIZE:
413 if (filesize (&value) < 0)
416 case RLIMIT_PIPESIZE:
417 if (pipesize (&value) < 0)
420 case RLIMIT_OPENFILES:
421 value = (RLIMTYPE)getdtablesize ();
424 if (getmaxvm (mode, &value) < 0)
427 case RLIMIT_MAXUPROC:
428 if (getmaxuprc (mode, &value) < 0)
440 #if defined (HAVE_RESOURCE)
441 if (getrlimit (limits[ind].parameter, &limit) < 0)
443 value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max;
445 if (limits[ind].parameter == RLIMIT_FILESIZE)
446 *limptr = value * 512; /* Ugh. */
459 set_limit (ind, newlim, mode)
464 #if defined (HAVE_RESOURCE)
469 if (limits[ind].parameter >= 256)
470 switch (limits[ind].parameter)
472 case RLIMIT_FILESIZE:
473 #if !defined (HAVE_RESOURCE)
474 return (ulimit (2, newlim / 512L));
480 case RLIMIT_OPENFILES:
481 #if defined (HAVE_SETDTABLESIZE)
482 # if defined (__CYGWIN__)
483 /* Grrr... Cygwin declares setdtablesize as void. */
484 setdtablesize (newlim);
487 return (setdtablesize (newlim));
490 case RLIMIT_PIPESIZE:
492 case RLIMIT_MAXUPROC:
499 #if defined (HAVE_RESOURCE)
500 if (getrlimit (limits[ind].parameter, &limit) < 0)
503 if (limits[ind].parameter == RLIMIT_FILESIZE)
504 newlim /= 512; /* Ugh. */
506 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
507 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
508 (limit.rlim_cur <= limit.rlim_max))
509 ? limit.rlim_max : newlim;
510 if (mode & LIMIT_SOFT)
511 limit.rlim_cur = val;
512 if (mode & LIMIT_HARD)
513 limit.rlim_max = val;
515 return (setrlimit (limits[ind].parameter, &limit));
524 getmaxvm (mode, valuep)
528 #if defined (HAVE_RESOURCE)
530 RLIMTYPE maxdata, maxstack;
532 if (getrlimit (RLIMIT_DATA, &rl) < 0)
535 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
537 if (getrlimit (RLIMIT_STACK, &rl) < 0)
540 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
542 /* Protect against overflow. */
543 *valuep = (maxdata / 1024L) + (maxstack / 1024L);
548 #endif /* HAVE_RESOURCE */
555 #if !defined (HAVE_RESOURCE)
557 if ((result = ulimit (1, 0L)) < 0)
561 *valuep = (RLIMTYPE) result;
563 *valuep = (RLIMTYPE) result * 512L;
576 #if defined (PIPE_BUF)
577 /* This is defined on Posix systems. */
578 *valuep = (RLIMTYPE) PIPE_BUF;
581 # if defined (PIPESIZE)
582 /* This is defined by running a program from the Makefile. */
583 *valuep = (RLIMTYPE) PIPESIZE;
588 # endif /* PIPESIZE */
589 #endif /* PIPE_BUF */
593 getmaxuprc (mode, valuep)
597 # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
599 maxchild = sysconf (_SC_CHILD_MAX);
603 *valuep = (RLIMTYPE) maxchild;
605 # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
606 # if defined (MAXUPRC)
607 *valuep = (RLIMTYPE) MAXUPRC;
612 # endif /* !MAXUPRC */
613 # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
617 print_all_limits (mode)
626 for (i = 0; limits[i].option > 0; i++)
628 if (get_limit (i, mode, &value) < 0)
630 fprintf (stderr, DESCFMT, limits[i].description);
631 builtin_error ("cannot get limit: %s", strerror (errno));
634 printone (i, value, 1);
639 printone (limind, curlim, pdesc)
645 printf (DESCFMT, limits[limind].description);
646 if (curlim == RLIM_INFINITY)
649 print_rlimtype ((curlim / limits[limind].block_factor), 1);