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 [-SHacdfmstpnuv [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 -m the maximum resident set size
38 -s the maximum stack size
39 -t the maximum amount of cpu time in seconds
40 -f the maximum size of files created by the shell
41 -p the pipe buffer size
42 -n the maximum number of open file descriptors
43 -u the maximum number of user processes
44 -v the size of virtual memory
46 If LIMIT is given, it is the new value of the specified resource.
47 Otherwise, the current value of the specified resource is printed.
48 If no option is given, then -f is assumed. Values are in 1k
49 increments, except for -t, which is in seconds, -p, which is in
50 increments of 512 bytes, and -u, which is an unscaled number of
55 #include <sys/types.h>
56 #include <sys/param.h>
65 #if defined (HAVE_RESOURCE)
66 # include <sys/time.h>
67 # include <sys/resource.h>
69 # include <sys/times.h>
72 #if defined (HAVE_UNISTD_H)
76 #if defined (HAVE_LIMITS_H)
80 /* Check for the most basic symbols. If they aren't present, this
81 system's <sys/resource.h> isn't very useful to us. */
82 #if !defined (RLIMIT_FSIZE) || defined (GETRLIMIT_MISSING)
86 #if !defined (RLIMTYPE)
87 # define RLIMTYPE long
88 # define string_to_rlimtype string_to_long
89 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
92 static void print_long ();
94 /* **************************************************************** */
96 /* Ulimit builtin and Hacks. */
98 /* **************************************************************** */
100 /* Block size for ulimit operations. */
101 #define ULIMIT_BLOCK_SIZE ((long)1024)
103 #define u_FILE_SIZE 0x001
104 #define u_MAX_BREAK_VAL 0x002
105 #define u_PIPE_SIZE 0x004
106 #define u_CORE_FILE_SIZE 0x008
107 #define u_DATA_SEG_SIZE 0x010
108 #define u_PHYS_MEM_SIZE 0x020
109 #define u_CPU_TIME_LIMIT 0x040
110 #define u_STACK_SIZE 0x080
111 #define u_NUM_OPEN_FILES 0x100
112 #define u_MAX_VIRTUAL_MEM 0x200
113 #define u_MAX_USER_PROCS 0x400
115 #define u_ALL_LIMITS 0x7ff
117 #if !defined (RLIM_INFINITY)
118 # define RLIM_INFINITY 0x7fffffff
121 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
122 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
123 # define RLIMIT_NOFILE RLIMIT_OFILE
124 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
126 #define LIMIT_HARD 0x01
127 #define LIMIT_SOFT 0x02
129 static RLIMTYPE shell_ulimit ();
130 static RLIMTYPE pipesize ();
131 static RLIMTYPE open_files ();
133 #if defined (HAVE_RESOURCE)
134 static RLIMTYPE getmaxvm ();
135 #endif /* HAVE_RESOURCE */
137 static void print_specific_limits ();
138 static void print_all_limits ();
142 /* Return 1 if the limit associated with CMD can be raised from CURRENT
143 to NEW. This is for USG systems without HAVE_RESOURCE, most of which
144 do not allow any user other than root to raise limits. There are,
145 however, exceptions. */
146 #if !defined (HAVE_RESOURCE)
148 canraise (cmd, current, new)
150 RLIMTYPE current, new;
152 # if defined (HAVE_SETDTABLESIZE)
153 if (cmd == u_NUM_OPEN_FILES)
155 # endif /* HAVE_SETDTABLSIZE */
157 return ((current > new) || (current_user.uid == 0));
159 #endif /* !HAVE_RESOURCE */
161 /* Report or set limits associated with certain per-process resources.
162 See the help documentation in builtins.c for a full description.
164 Rewritten by Chet Ramey 6/30/91. */
166 ulimit_builtin (list)
167 register WORD_LIST *list;
170 int c, setting, cmd, mode, verbose_print, opt_eof;
171 int all_limits, specific_limits;
173 RLIMTYPE current_limit, real_limit, limit;
175 c = mode = verbose_print = opt_eof = 0;
176 limit = (RLIMTYPE)-1;
180 cmd = setting = all_limits = specific_limits = 0;
181 block_factor = ULIMIT_BLOCK_SIZE;
184 if (list && !opt_eof && *list->word->word == '-')
186 s = &(list->word->word[1]);
189 while (*s && (c = *s++))
193 #define ADD_CMD(x) { if (cmd) specific_limits++; cmd |= (x); }
195 case '-': /* ulimit -- */
204 ADD_CMD (u_FILE_SIZE);
207 #if defined (HAVE_RESOURCE)
208 /* -S and -H are modifiers, not real options. */
218 ADD_CMD (u_CORE_FILE_SIZE);
222 ADD_CMD (u_DATA_SEG_SIZE);
227 ADD_CMD (u_PHYS_MEM_SIZE);
232 ADD_CMD (u_CPU_TIME_LIMIT);
233 block_factor = 1; /* seconds */
237 ADD_CMD (u_STACK_SIZE);
241 ADD_CMD (u_MAX_VIRTUAL_MEM);
246 ADD_CMD (u_MAX_USER_PROCS);
250 #endif /* HAVE_RESOURCE */
253 ADD_CMD (u_PIPE_SIZE);
258 ADD_CMD (u_NUM_OPEN_FILES);
262 default: /* error_case: */
266 #if !defined (HAVE_RESOURCE)
267 builtin_error("usage: ulimit [-afnp] [new limit]");
269 builtin_error("usage: ulimit [-SHacmdstfnpuv] [new limit]");
278 print_all_limits (mode);
279 return (EXECUTION_SUCCESS);
284 print_specific_limits (cmd, mode);
293 /* If an argument was supplied for the command, then we want to
294 set the limit. Note that `ulimit something' means a command
295 of -f with argument `something'. */
298 if (opt_eof || (*list->word->word != '-'))
300 s = list->word->word;
303 if (STREQ (s, "unlimited"))
304 limit = RLIM_INFINITY;
305 else if (all_digits (s))
306 limit = string_to_rlimtype (s);
309 builtin_error ("bad non-numeric arg `%s'", s);
310 return (EXECUTION_FAILURE);
318 if (limit == RLIM_INFINITY)
321 real_limit = limit * block_factor;
323 /* If more than one option is given, list each in a verbose format,
324 the same that is used for -a. */
325 if (!setting && verbose_print)
327 print_specific_limits (cmd, mode);
331 current_limit = shell_ulimit (cmd, real_limit, 0, mode);
335 #if !defined (HAVE_RESOURCE)
336 /* Most USG systems do not most allow limits to be raised by any
337 user other than root. There are, however, exceptions. */
338 if (canraise (cmd, current_limit, real_limit) == 0)
340 builtin_error ("cannot raise limit: %s", strerror (EPERM));
341 return (EXECUTION_FAILURE);
343 #endif /* !HAVE_RESOURCE */
345 if (shell_ulimit (cmd, real_limit, 1, mode) == (RLIMTYPE)-1)
347 builtin_error ("cannot raise limit: %s", strerror (errno));
348 return (EXECUTION_FAILURE);
355 if (current_limit < 0)
356 builtin_error ("cannot get limit: %s", strerror (errno));
357 else if (current_limit != RLIM_INFINITY)
358 print_rlimtype ((current_limit / block_factor), 1);
360 printf ("unlimited\n");
365 return (EXECUTION_SUCCESS);
368 /* The ulimit that we call from within Bash.
370 WHICH says which limit to twiddle; SETTING is non-zero if NEWLIM
371 contains the desired new limit. Otherwise, the existing limit is
372 returned. If mode & LIMIT_HARD, the hard limit is used; if
373 mode & LIMIT_SOFT, the soft limit. Both may be set by specifying
374 -H and -S; if both are specified, or if neither is specified, the
375 soft limit will be returned.
377 Systems without BSD resource limits can specify only u_FILE_SIZE.
378 This includes most USG systems.
380 Chet Ramey supplied the BSD resource limit code. */
382 shell_ulimit (which, newlim, setting, mode)
383 int which, setting, mode;
386 #if defined (HAVE_RESOURCE)
396 #if !defined (HAVE_RESOURCE)
401 /* ulimit () returns a number that is in 512 byte blocks, thus we
402 must multiply it by 512 to get back to bytes. This is false
403 only under HP/UX 6.x. */
406 result = ulimit (1, 0L);
408 # if defined (hpux) && !defined (_POSIX_VERSION)
411 return (result * 512);
412 # endif /* hpux 6.x */
415 return (ulimit (2, newlim / 512L));
419 #else /* defined (HAVE_RESOURCE) */
425 case u_CORE_FILE_SIZE:
429 case u_DATA_SEG_SIZE:
434 case u_PHYS_MEM_SIZE:
435 # if defined (RLIMIT_RSS)
437 # else /* !RLIMIT_RSS */
439 return ((RLIMTYPE)-1);
440 # endif /* !RLIMIT_RSS */
445 case u_CPU_TIME_LIMIT:
446 #if defined (RLIMIT_CPU)
451 return ((RLIMTYPE)-1);
452 # endif /* !RLIMIT_CPU */
460 if (getrlimit (cmd, &limit) != 0)
461 return ((RLIMTYPE)-1);
465 if (mode & LIMIT_SOFT)
466 return (limit.rlim_cur);
468 return (limit.rlim_max);
472 if (mode & LIMIT_SOFT)
474 /* Non-root users are only allowed to raise a limit up to the
475 hard limit, not to infinity. */
476 if (current_user.euid != 0 && newlim == RLIM_INFINITY)
477 limit.rlim_cur = limit.rlim_max;
479 limit.rlim_cur = newlim;
481 if (mode & LIMIT_HARD)
482 limit.rlim_max = newlim;
484 return (setrlimit (cmd, &limit));
489 #endif /* HAVE_RESOURCE */
491 /* You can't get or set the pipe size with getrlimit, so we have to
497 return ((RLIMTYPE)-1);
499 return (pipesize ());
501 case u_NUM_OPEN_FILES:
504 #if defined (HAVE_RESOURCE) && defined (RLIMIT_NOFILE)
508 # if defined (HAVE_SETDTABLESIZE)
509 return (setdtablesize (newlim));
512 return ((RLIMTYPE)-1);
513 # endif /* HAVE_SETDTABLESIZE */
514 #endif /* !HAVE_RESOURCE || !RLIMIT_NOFILE */
517 return (open_files (mode));
519 case u_MAX_VIRTUAL_MEM:
523 return ((RLIMTYPE)-1);
527 #if defined (HAVE_RESOURCE)
528 return (getmaxvm (mode));
529 #else /* !HAVE_RESOURCE */
531 return ((RLIMTYPE)-1);
532 #endif /* !HAVE_RESOURCE */
535 case u_MAX_USER_PROCS:
536 #if defined (HAVE_RESOURCE) && defined (RLIMIT_NPROC)
539 #else /* !HAVE_RESOURCE || !RLIMIT_NPROC */
541 return ((RLIMTYPE)-1);
542 #endif /* !HAVE_RESOURCE || !RLIMIT_NPROC */
546 return ((RLIMTYPE)-1);
550 #if defined (HAVE_RESOURCE)
557 #if defined (RLIMIT_VMEM)
558 if (getrlimit (RLIMIT_VMEM, &rl) < 0)
559 return ((RLIMTYPE)-1);
561 return (((mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max) / 1024L);
562 #else /* !RLIMIT_VMEM */
563 RLIMTYPE maxdata, maxstack;
565 if (getrlimit (RLIMIT_DATA, &rl) < 0)
566 return ((RLIMTYPE)-1);
568 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
570 if (getrlimit (RLIMIT_STACK, &rl) < 0)
571 return ((RLIMTYPE)-1);
573 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
575 /* Protect against overflow. */
576 return ((maxdata / 1024L) + (maxstack / 1024L));
577 #endif /* !RLIMIT_VMEM */
579 #endif /* HAVE_RESOURCE */
585 #if !defined (RLIMIT_NOFILE)
586 return ((RLIMTYPE)getdtablesize ());
590 getrlimit (RLIMIT_NOFILE, &rl);
591 if (mode & LIMIT_SOFT)
592 return (rl.rlim_cur);
594 return (rl.rlim_max);
601 #if defined (PIPE_BUF)
602 /* This is defined on Posix systems. */
603 return ((RLIMTYPE) PIPE_BUF);
605 # if defined (PIPESIZE)
606 /* This is defined by running a program from the Makefile. */
607 return ((RLIMTYPE) PIPESIZE);
610 return ((RLIMTYPE)-1);
611 # endif /* PIPESIZE */
612 #endif /* PIPE_BUF */
615 /* ulimit(2) returns information about file size limits in terms of 512-byte
616 blocks. This is the factor by which to divide to turn it into information
617 in terms of 1024-byte blocks. Except for hpux 6.x, which returns it in
619 #if !defined (hpux) || defined (_POSIX_VERSION)
620 # define ULIMIT_DIVISOR 2
622 # define ULIMIT_DIVISOR 1024
625 #if defined (HAVE_RESOURCE)
628 int option_cmd; /* The ulimit command for this limit. */
629 int parameter; /* Parameter to pass to getrlimit (). */
630 int block_factor; /* Blocking factor for specific limit. */
631 char *description; /* Descriptive string to output. */
632 } BSD_RESOURCE_LIMITS;
634 static BSD_RESOURCE_LIMITS limits[] = {
635 { u_CORE_FILE_SIZE, RLIMIT_CORE, 1024, "core file size (blocks)" },
636 { u_DATA_SEG_SIZE, RLIMIT_DATA, 1024, "data seg size (kbytes)" },
637 { u_FILE_SIZE, RLIMIT_FSIZE, 1024, "file size (blocks)" },
638 #if !defined (USGr4) && defined (RLIMIT_RSS)
639 { u_PHYS_MEM_SIZE, RLIMIT_RSS, 1024, "max memory size (kbytes)" },
640 #endif /* USGr4 && RLIMIT_RSS */
641 { u_STACK_SIZE, RLIMIT_STACK, 1024, "stack size (kbytes)" },
642 #if defined (RLIMIT_CPU)
643 { u_CPU_TIME_LIMIT, RLIMIT_CPU, 1, "cpu time (seconds)" },
644 #endif /* RLIMIT_CPU */
645 #if defined (RLIMIT_NPROC)
646 { u_MAX_USER_PROCS, RLIMIT_NPROC, 1, "max user processes" },
647 #endif /* RLIMIT_NPROC */
648 { 0, 0, 0, (char *)NULL }
652 print_bsd_limit (i, mode)
658 getrlimit (limits[i].parameter, &rl);
659 if (mode & LIMIT_HARD)
663 printf ("%-25s", limits[i].description);
664 if (limit == RLIM_INFINITY)
665 printf ("unlimited\n");
667 print_rlimtype ((limit / limits[i].block_factor), 1);
671 print_specific_bsd_limits (cmd, mode)
676 for (i = 0; limits[i].option_cmd; i++)
677 if (cmd & limits[i].option_cmd)
678 print_bsd_limit (i, mode);
680 #endif /* HAVE_RESOURCE */
682 /* Print the limits corresponding to a specific set of resources. This is
683 called when an option string contains more than one character (e.g. -at),
684 because limits may not be specified with that kind of argument. */
686 print_specific_limits (cmd, mode)
692 #if defined (HAVE_RESOURCE)
693 print_specific_bsd_limits (cmd, mode);
694 #else /* !HAVE_RESOURCE */
695 if (cmd & u_FILE_SIZE)
697 printf ("%-25s", "file size (blocks)");
698 print_rlimtype ((ulimit (1, 0L) / ULIMIT_DIVISOR), 1);
700 #endif /* !HAVE_RESOURCE */
702 if (cmd & u_PIPE_SIZE)
704 printf ("%-25s", "pipe size (512 bytes)");
705 print_rlimtype ((pipesize () / 512), 1);
708 if (cmd & u_NUM_OPEN_FILES)
710 printf ("%-25s", "open files");
711 print_rlimtype (open_files (mode), 1);
714 #if defined (HAVE_RESOURCE)
715 if (cmd & u_MAX_VIRTUAL_MEM)
717 printf ("%-25s", "virtual memory (kbytes)");
718 print_rlimtype (getmaxvm (mode), 1);
720 #endif /* HAVE_RESOURCE */
724 print_all_limits (mode)
730 print_specific_limits (u_ALL_LIMITS, mode);