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;
224 for (i = 0; limits[i].option > 0; i++)
225 if (limits[i].option == opt)
230 static char optstring[4 + 2 * NCMDS];
232 /* Report or set limits associated with certain per-process resources.
233 See the help documentation in builtins.c for a full description. */
235 ulimit_builtin (list)
236 register WORD_LIST *list;
239 int c, limind, mode, opt, all_limits;
245 /* Idea stolen from pdksh -- build option string the first time called. */
246 if (optstring[0] == 0)
249 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
250 for (c = 0; limits[c].option > 0; c++)
252 *s++ = limits[c].option;
258 /* Initialize the command list. */
260 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
263 reset_internal_getopt ();
264 while ((opt = internal_getopt (list, optstring)) != -1)
272 /* -S and -H are modifiers, not real options. */
286 if (ncmd >= cmdlistsz)
287 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
288 cmdlist[ncmd].cmd = opt;
289 cmdlist[ncmd++].arg = list_optarg;
297 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
298 return (EXECUTION_SUCCESS);
301 /* default is `ulimit -f' */
304 cmdlist[ncmd].cmd = 'f';
305 /* `ulimit something' is same as `ulimit -f something' */
306 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
311 /* verify each command in the list. */
312 for (c = 0; c < ncmd; c++)
314 limind = _findlim (cmdlist[c].cmd);
317 builtin_error ("bad command: `%c'", cmdlist[c].cmd);
322 for (c = 0; c < ncmd; c++)
323 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
324 return (EXECUTION_FAILURE);
326 return (EXECUTION_SUCCESS);
330 ulimit_internal (cmd, cmdarg, mode, multiple)
335 int opt, limind, setting;
337 RLIMTYPE current_limit, real_limit, limit;
339 limit = RLIM_INVALID;
340 setting = cmdarg != 0;
341 limind = _findlim (cmd);
343 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
344 opt = get_limit (limind, mode, ¤t_limit);
347 builtin_error ("cannot get limit: %s", strerror (errno));
348 return (EXECUTION_FAILURE);
351 if (setting == 0) /* print the value of the specified limit */
353 printone (limind, current_limit, multiple);
354 return (EXECUTION_SUCCESS);
357 /* Setting the limit. */
358 if (STREQ (cmdarg, "unlimited"))
359 limit = RLIM_INFINITY;
360 else if (all_digits (cmdarg))
361 limit = string_to_rlimtype (cmdarg);
364 builtin_error ("bad non-numeric arg `%s'", cmdarg);
365 return (EXECUTION_FAILURE);
368 block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor;
369 real_limit = limit * block_factor;
371 if (set_limit (limind, real_limit, mode) < 0)
373 builtin_error ("cannot modify limit: %s", strerror (errno));
374 return (EXECUTION_FAILURE);
376 return (EXECUTION_SUCCESS);
380 get_limit (ind, mode, limptr)
385 #if defined (HAVE_RESOURCE)
389 if (limits[ind].parameter >= 256)
391 switch (limits[ind].parameter)
393 case RLIMIT_FILESIZE:
396 case RLIMIT_PIPESIZE:
399 case RLIMIT_OPENFILES:
400 value = (RLIMTYPE)getdtablesize ();
403 value = getmaxvm (mode);
405 case RLIMIT_MAXUPROC:
406 value = getmaxuprc (mode);
413 return ((value == RLIM_INVALID) ? -1 : 0);
417 #if defined (HAVE_RESOURCE)
418 if (getrlimit (limits[ind].parameter, &limit) < 0)
420 value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max;
431 set_limit (ind, newlim, mode)
436 #if defined (HAVE_RESOURCE)
441 if (limits[ind].parameter >= 256)
442 switch (limits[ind].parameter)
444 case RLIMIT_FILESIZE:
445 #if !defined (HAVE_RESOURCE)
446 return (ulimit (2, newlim / 512L));
449 case RLIMIT_OPENFILES:
450 #if defined (HAVE_SETDTABLESIZE)
451 return (setdtablesize (newlim));
453 case RLIMIT_PIPESIZE:
455 case RLIMIT_MAXUPROC:
462 #if defined (HAVE_RESOURCE)
463 if (getrlimit (limits[ind].parameter, &limit) < 0)
465 val = (current_user.euid != 0 && newlim == RLIM_INFINITY)
466 ? limit.rlim_max : newlim;
467 if (mode & LIMIT_SOFT)
468 limit.rlim_cur = val;
469 if (mode & LIMIT_HARD)
470 limit.rlim_max = val;
472 return (setrlimit (limits[ind].parameter, &limit));
484 #if defined (HAVE_RESOURCE)
486 RLIMTYPE maxdata, maxstack;
488 if (getrlimit (RLIMIT_DATA, &rl) < 0)
489 return (RLIM_INVALID);
491 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
493 if (getrlimit (RLIMIT_STACK, &rl) < 0)
494 return (RLIM_INVALID);
496 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
498 /* Protect against overflow. */
499 return ((maxdata / 1024L) + (maxstack / 1024L));
503 #endif /* HAVE_RESOURCE */
509 #if !defined (HAVE_RESOURCE)
510 return ((RLIMTYPE)ulimit (1, 0L));
520 #if defined (PIPE_BUF)
521 /* This is defined on Posix systems. */
522 return ((RLIMTYPE) PIPE_BUF);
524 # if defined (PIPESIZE)
525 /* This is defined by running a program from the Makefile. */
526 return ((RLIMTYPE) PIPESIZE);
530 # endif /* PIPESIZE */
531 #endif /* PIPE_BUF */
538 # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
539 return ((RLIMTYPE)sysconf (_SC_CHILD_MAX));
540 # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
541 # if defined (MAXUPRC)
542 return ((RLIMTYPE)MAXUPRC);
546 # endif /* !MAXUPRC */
547 # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
551 print_all_limits (mode)
560 for (i = 0; limits[i].option > 0; i++)
562 if (get_limit (i, mode, &value) < 0)
563 value = RLIM_INVALID;
564 printone (i, value, 1);
569 printone (limind, curlim, pdesc)
575 printf (DESCFMT, limits[limind].description);
576 if (curlim == RLIM_INFINITY)
578 else if (curlim == RLIM_INVALID)
579 printf ("cannot get limit: %s\n", strerror (errno));
581 print_rlimtype ((curlim / limits[limind].block_factor), 1);