]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/ulimit.def
1947c367df6d5a736338e3bace4f4f5ed3a399ff
[thirdparty/bash.git] / builtins / ulimit.def
1 This file is ulimit.def, from which is created ulimit.c.
2 It implements the builtin "ulimit" in Bash.
3
4 Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
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
11 version.
12
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
16 for more details.
17
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.
21
22 $PRODUCES ulimit.c
23
24 $BUILTIN ulimit
25 $FUNCTION ulimit_builtin
26 $DEPENDS_ON !MINIX
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:
31
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
45
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
51 processes.
52 $END
53
54 #include <stdio.h>
55 #include <sys/types.h>
56 #include <sys/param.h>
57 #include <errno.h>
58 #include "../shell.h"
59 #include "pipesize.h"
60
61 #if !defined (errno)
62 extern int errno;
63 #endif
64
65 #if defined (HAVE_RESOURCE)
66 # include <sys/time.h>
67 # include <sys/resource.h>
68 #else
69 # include <sys/times.h>
70 #endif
71
72 #if defined (HAVE_UNISTD_H)
73 # include <unistd.h>
74 #endif
75
76 #if defined (HAVE_LIMITS_H)
77 # include <limits.h>
78 #endif
79
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)
83 # undef HAVE_RESOURCE
84 #endif
85
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" : "")
90 #endif
91
92 static void print_long ();
93
94 /* **************************************************************** */
95 /* */
96 /* Ulimit builtin and Hacks. */
97 /* */
98 /* **************************************************************** */
99
100 /* Block size for ulimit operations. */
101 #define ULIMIT_BLOCK_SIZE ((long)1024)
102
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
114
115 #define u_ALL_LIMITS 0x7ff
116
117 #if !defined (RLIM_INFINITY)
118 # define RLIM_INFINITY 0x7fffffff
119 #endif
120
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 */
125
126 #define LIMIT_HARD 0x01
127 #define LIMIT_SOFT 0x02
128
129 static RLIMTYPE shell_ulimit ();
130 static RLIMTYPE pipesize ();
131 static RLIMTYPE open_files ();
132
133 #if defined (HAVE_RESOURCE)
134 static RLIMTYPE getmaxvm ();
135 #endif /* HAVE_RESOURCE */
136
137 static void print_specific_limits ();
138 static void print_all_limits ();
139
140 static char t[2];
141
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)
147 static int
148 canraise (cmd, current, new)
149 int cmd;
150 RLIMTYPE current, new;
151 {
152 # if defined (HAVE_SETDTABLESIZE)
153 if (cmd == u_NUM_OPEN_FILES)
154 return (1);
155 # endif /* HAVE_SETDTABLSIZE */
156
157 return ((current > new) || (current_user.uid == 0));
158 }
159 #endif /* !HAVE_RESOURCE */
160
161 /* Report or set limits associated with certain per-process resources.
162 See the help documentation in builtins.c for a full description.
163
164 Rewritten by Chet Ramey 6/30/91. */
165 int
166 ulimit_builtin (list)
167 register WORD_LIST *list;
168 {
169 register char *s;
170 int c, setting, cmd, mode, verbose_print, opt_eof;
171 int all_limits, specific_limits;
172 long block_factor;
173 RLIMTYPE current_limit, real_limit, limit;
174
175 c = mode = verbose_print = opt_eof = 0;
176 limit = (RLIMTYPE)-1;
177
178 do
179 {
180 cmd = setting = all_limits = specific_limits = 0;
181 block_factor = ULIMIT_BLOCK_SIZE;
182
183 /* read_options: */
184 if (list && !opt_eof && *list->word->word == '-')
185 {
186 s = &(list->word->word[1]);
187 list = list->next;
188
189 while (*s && (c = *s++))
190 {
191 switch (c)
192 {
193 #define ADD_CMD(x) { if (cmd) specific_limits++; cmd |= (x); }
194
195 case '-': /* ulimit -- */
196 opt_eof++;
197 break;
198
199 case 'a':
200 all_limits++;
201 break;
202
203 case 'f':
204 ADD_CMD (u_FILE_SIZE);
205 break;
206
207 #if defined (HAVE_RESOURCE)
208 /* -S and -H are modifiers, not real options. */
209 case 'S':
210 mode |= LIMIT_SOFT;
211 break;
212
213 case 'H':
214 mode |= LIMIT_HARD;
215 break;
216
217 case 'c':
218 ADD_CMD (u_CORE_FILE_SIZE);
219 break;
220
221 case 'd':
222 ADD_CMD (u_DATA_SEG_SIZE);
223 break;
224
225 #if !defined (USGr4)
226 case 'm':
227 ADD_CMD (u_PHYS_MEM_SIZE);
228 break;
229 #endif /* USGr4 */
230
231 case 't':
232 ADD_CMD (u_CPU_TIME_LIMIT);
233 block_factor = 1; /* seconds */
234 break;
235
236 case 's':
237 ADD_CMD (u_STACK_SIZE);
238 break;
239
240 case 'v':
241 ADD_CMD (u_MAX_VIRTUAL_MEM);
242 block_factor = 1;
243 break;
244
245 case 'u':
246 ADD_CMD (u_MAX_USER_PROCS);
247 block_factor = 1;
248 break;
249
250 #endif /* HAVE_RESOURCE */
251
252 case 'p':
253 ADD_CMD (u_PIPE_SIZE);
254 block_factor = 512;
255 break;
256
257 case 'n':
258 ADD_CMD (u_NUM_OPEN_FILES);
259 block_factor = 1;
260 break;
261
262 default: /* error_case: */
263 t[0] = c;
264 t[1] = '\0';
265 bad_option (t);
266 #if !defined (HAVE_RESOURCE)
267 builtin_error("usage: ulimit [-afnp] [new limit]");
268 #else
269 builtin_error("usage: ulimit [-SHacmdstfnpuv] [new limit]");
270 #endif
271 return (EX_USAGE);
272 }
273 }
274 }
275
276 if (all_limits)
277 {
278 print_all_limits (mode);
279 return (EXECUTION_SUCCESS);
280 }
281
282 if (specific_limits)
283 {
284 print_specific_limits (cmd, mode);
285 if (list)
286 verbose_print++;
287 continue;
288 }
289
290 if (cmd == 0)
291 cmd = u_FILE_SIZE;
292
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'. */
296 if (list)
297 {
298 if (opt_eof || (*list->word->word != '-'))
299 {
300 s = list->word->word;
301 list = list->next;
302
303 if (STREQ (s, "unlimited"))
304 limit = RLIM_INFINITY;
305 else if (all_digits (s))
306 limit = string_to_rlimtype (s);
307 else
308 {
309 builtin_error ("bad non-numeric arg `%s'", s);
310 return (EXECUTION_FAILURE);
311 }
312 setting++;
313 }
314 else if (!opt_eof)
315 verbose_print++;
316 }
317
318 if (limit == RLIM_INFINITY)
319 block_factor = 1;
320
321 real_limit = limit * block_factor;
322
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)
326 {
327 print_specific_limits (cmd, mode);
328 continue;
329 }
330
331 current_limit = shell_ulimit (cmd, real_limit, 0, mode);
332
333 if (setting)
334 {
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)
339 {
340 builtin_error ("cannot raise limit: %s", strerror (EPERM));
341 return (EXECUTION_FAILURE);
342 }
343 #endif /* !HAVE_RESOURCE */
344
345 if (shell_ulimit (cmd, real_limit, 1, mode) == (RLIMTYPE)-1)
346 {
347 builtin_error ("cannot raise limit: %s", strerror (errno));
348 return (EXECUTION_FAILURE);
349 }
350
351 continue;
352 }
353 else
354 {
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);
359 else
360 printf ("unlimited\n");
361 }
362 }
363 while (list);
364
365 return (EXECUTION_SUCCESS);
366 }
367
368 /* The ulimit that we call from within Bash.
369
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.
376
377 Systems without BSD resource limits can specify only u_FILE_SIZE.
378 This includes most USG systems.
379
380 Chet Ramey supplied the BSD resource limit code. */
381 static RLIMTYPE
382 shell_ulimit (which, newlim, setting, mode)
383 int which, setting, mode;
384 RLIMTYPE newlim;
385 {
386 #if defined (HAVE_RESOURCE)
387 struct rlimit limit;
388 int cmd;
389
390 if (mode == 0)
391 mode |= LIMIT_SOFT;
392 #endif
393
394 switch (which)
395 {
396 #if !defined (HAVE_RESOURCE)
397
398 case u_FILE_SIZE:
399 if (!setting)
400 {
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. */
404 RLIMTYPE result;
405
406 result = ulimit (1, 0L);
407
408 # if defined (hpux) && !defined (_POSIX_VERSION)
409 return (result);
410 # else
411 return (result * 512);
412 # endif /* hpux 6.x */
413 }
414 else
415 return (ulimit (2, newlim / 512L));
416
417 break;
418
419 #else /* defined (HAVE_RESOURCE) */
420
421 case u_FILE_SIZE:
422 cmd = RLIMIT_FSIZE;
423 goto do_ulimit;
424
425 case u_CORE_FILE_SIZE:
426 cmd = RLIMIT_CORE;
427 goto do_ulimit;
428
429 case u_DATA_SEG_SIZE:
430 cmd = RLIMIT_DATA;
431 goto do_ulimit;
432
433 #if !defined (USGr4)
434 case u_PHYS_MEM_SIZE:
435 # if defined (RLIMIT_RSS)
436 cmd = RLIMIT_RSS;
437 # else /* !RLIMIT_RSS */
438 errno = EINVAL;
439 return ((RLIMTYPE)-1);
440 # endif /* !RLIMIT_RSS */
441
442 goto do_ulimit;
443 #endif /* USGr4 */
444
445 case u_CPU_TIME_LIMIT:
446 #if defined (RLIMIT_CPU)
447 cmd = RLIMIT_CPU;
448 goto do_ulimit;
449 #else
450 errno = EINVAL;
451 return ((RLIMTYPE)-1);
452 # endif /* !RLIMIT_CPU */
453
454
455 case u_STACK_SIZE:
456 cmd = RLIMIT_STACK;
457
458 do_ulimit:
459
460 if (getrlimit (cmd, &limit) != 0)
461 return ((RLIMTYPE)-1);
462
463 if (!setting)
464 {
465 if (mode & LIMIT_SOFT)
466 return (limit.rlim_cur);
467 else
468 return (limit.rlim_max);
469 }
470 else
471 {
472 if (mode & LIMIT_SOFT)
473 {
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;
478 else
479 limit.rlim_cur = newlim;
480 }
481 if (mode & LIMIT_HARD)
482 limit.rlim_max = newlim;
483
484 return (setrlimit (cmd, &limit));
485 }
486
487 break;
488
489 #endif /* HAVE_RESOURCE */
490
491 /* You can't get or set the pipe size with getrlimit, so we have to
492 cheat. */
493 case u_PIPE_SIZE:
494 if (setting)
495 {
496 errno = EINVAL;
497 return ((RLIMTYPE)-1);
498 }
499 return (pipesize ());
500
501 case u_NUM_OPEN_FILES:
502 if (setting)
503 {
504 #if defined (HAVE_RESOURCE) && defined (RLIMIT_NOFILE)
505 cmd = RLIMIT_NOFILE;
506 goto do_ulimit;
507 #else
508 # if defined (HAVE_SETDTABLESIZE)
509 return (setdtablesize (newlim));
510 # else
511 errno = EINVAL;
512 return ((RLIMTYPE)-1);
513 # endif /* HAVE_SETDTABLESIZE */
514 #endif /* !HAVE_RESOURCE || !RLIMIT_NOFILE */
515 }
516 else
517 return (open_files (mode));
518
519 case u_MAX_VIRTUAL_MEM:
520 if (setting)
521 {
522 errno = EINVAL;
523 return ((RLIMTYPE)-1);
524 }
525 else
526 {
527 #if defined (HAVE_RESOURCE)
528 return (getmaxvm (mode));
529 #else /* !HAVE_RESOURCE */
530 errno = EINVAL;
531 return ((RLIMTYPE)-1);
532 #endif /* !HAVE_RESOURCE */
533 }
534
535 case u_MAX_USER_PROCS:
536 #if defined (HAVE_RESOURCE) && defined (RLIMIT_NPROC)
537 cmd = RLIMIT_NPROC;
538 goto do_ulimit;
539 #else /* !HAVE_RESOURCE || !RLIMIT_NPROC */
540 errno = EINVAL;
541 return ((RLIMTYPE)-1);
542 #endif /* !HAVE_RESOURCE || !RLIMIT_NPROC */
543
544 default:
545 errno = EINVAL;
546 return ((RLIMTYPE)-1);
547 }
548 }
549
550 #if defined (HAVE_RESOURCE)
551 static RLIMTYPE
552 getmaxvm (mode)
553 int mode;
554 {
555 struct rlimit rl;
556
557 #if defined (RLIMIT_VMEM)
558 if (getrlimit (RLIMIT_VMEM, &rl) < 0)
559 return ((RLIMTYPE)-1);
560 else
561 return (((mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max) / 1024L);
562 #else /* !RLIMIT_VMEM */
563 RLIMTYPE maxdata, maxstack;
564
565 if (getrlimit (RLIMIT_DATA, &rl) < 0)
566 return ((RLIMTYPE)-1);
567 else
568 maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
569
570 if (getrlimit (RLIMIT_STACK, &rl) < 0)
571 return ((RLIMTYPE)-1);
572 else
573 maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
574
575 /* Protect against overflow. */
576 return ((maxdata / 1024L) + (maxstack / 1024L));
577 #endif /* !RLIMIT_VMEM */
578 }
579 #endif /* HAVE_RESOURCE */
580
581 static RLIMTYPE
582 open_files (mode)
583 int mode;
584 {
585 #if !defined (RLIMIT_NOFILE)
586 return ((RLIMTYPE)getdtablesize ());
587 #else
588 struct rlimit rl;
589
590 getrlimit (RLIMIT_NOFILE, &rl);
591 if (mode & LIMIT_SOFT)
592 return (rl.rlim_cur);
593 else
594 return (rl.rlim_max);
595 #endif
596 }
597
598 static RLIMTYPE
599 pipesize ()
600 {
601 #if defined (PIPE_BUF)
602 /* This is defined on Posix systems. */
603 return ((RLIMTYPE) PIPE_BUF);
604 #else
605 # if defined (PIPESIZE)
606 /* This is defined by running a program from the Makefile. */
607 return ((RLIMTYPE) PIPESIZE);
608 # else
609 errno = EINVAL;
610 return ((RLIMTYPE)-1);
611 # endif /* PIPESIZE */
612 #endif /* PIPE_BUF */
613 }
614
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
618 terms of bytes. */
619 #if !defined (hpux) || defined (_POSIX_VERSION)
620 # define ULIMIT_DIVISOR 2
621 #else
622 # define ULIMIT_DIVISOR 1024
623 #endif
624
625 #if defined (HAVE_RESOURCE)
626
627 typedef struct {
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;
633
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 }
649 };
650
651 static void
652 print_bsd_limit (i, mode)
653 int i, mode;
654 {
655 struct rlimit rl;
656 RLIMTYPE limit;
657
658 getrlimit (limits[i].parameter, &rl);
659 if (mode & LIMIT_HARD)
660 limit = rl.rlim_max;
661 else
662 limit = rl.rlim_cur;
663 printf ("%-25s", limits[i].description);
664 if (limit == RLIM_INFINITY)
665 printf ("unlimited\n");
666 else
667 print_rlimtype ((limit / limits[i].block_factor), 1);
668 }
669
670 static void
671 print_specific_bsd_limits (cmd, mode)
672 int cmd, mode;
673 {
674 register int i;
675
676 for (i = 0; limits[i].option_cmd; i++)
677 if (cmd & limits[i].option_cmd)
678 print_bsd_limit (i, mode);
679 }
680 #endif /* HAVE_RESOURCE */
681
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. */
685 static void
686 print_specific_limits (cmd, mode)
687 int cmd, mode;
688 {
689 if (mode == 0)
690 mode = LIMIT_SOFT;
691
692 #if defined (HAVE_RESOURCE)
693 print_specific_bsd_limits (cmd, mode);
694 #else /* !HAVE_RESOURCE */
695 if (cmd & u_FILE_SIZE)
696 {
697 printf ("%-25s", "file size (blocks)");
698 print_rlimtype ((ulimit (1, 0L) / ULIMIT_DIVISOR), 1);
699 }
700 #endif /* !HAVE_RESOURCE */
701
702 if (cmd & u_PIPE_SIZE)
703 {
704 printf ("%-25s", "pipe size (512 bytes)");
705 print_rlimtype ((pipesize () / 512), 1);
706 }
707
708 if (cmd & u_NUM_OPEN_FILES)
709 {
710 printf ("%-25s", "open files");
711 print_rlimtype (open_files (mode), 1);
712 }
713
714 #if defined (HAVE_RESOURCE)
715 if (cmd & u_MAX_VIRTUAL_MEM)
716 {
717 printf ("%-25s", "virtual memory (kbytes)");
718 print_rlimtype (getmaxvm (mode), 1);
719 }
720 #endif /* HAVE_RESOURCE */
721 }
722
723 static void
724 print_all_limits (mode)
725 int mode;
726 {
727 if (mode == 0)
728 mode |= LIMIT_SOFT;
729
730 print_specific_limits (u_ALL_LIMITS, mode);
731 }