]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/ulimit.def
a895c5e26de00a737a23a5b9173d83a8e5d08ca9
[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-2020 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
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20
21 $PRODUCES ulimit.c
22
23 $BUILTIN ulimit
24 $FUNCTION ulimit_builtin
25 $DEPENDS_ON !_MINIX
26 $SHORT_DOC ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]
27 Modify shell resource limits.
28
29 Provides control over the resources available to the shell and processes
30 it creates, on systems that allow such control.
31
32 Options:
33 -S use the `soft' resource limit
34 -H use the `hard' resource limit
35 -a all current limits are reported
36 -b the socket buffer size
37 -c the maximum size of core files created
38 -d the maximum size of a process's data segment
39 -e the maximum scheduling priority (`nice')
40 -f the maximum size of files written by the shell and its children
41 -i the maximum number of pending signals
42 -k the maximum number of kqueues allocated for this process
43 -l the maximum size a process may lock into memory
44 -m the maximum resident set size
45 -n the maximum number of open file descriptors
46 -p the pipe buffer size
47 -q the maximum number of bytes in POSIX message queues
48 -r the maximum real-time scheduling priority
49 -s the maximum stack size
50 -t the maximum amount of cpu time in seconds
51 -u the maximum number of user processes
52 -v the size of virtual memory
53 -x the maximum number of file locks
54 -P the maximum number of pseudoterminals
55 -R the maximum time a real-time process can run before blocking
56 -T the maximum number of threads
57
58 Not all options are available on all platforms.
59
60 If LIMIT is given, it is the new value of the specified resource; the
61 special LIMIT values `soft', `hard', and `unlimited' stand for the
62 current soft limit, the current hard limit, and no limit, respectively.
63 Otherwise, the current value of the specified resource is printed. If
64 no option is given, then -f is assumed.
65
66 Values are in 1024-byte increments, except for -t, which is in seconds,
67 -p, which is in increments of 512 bytes, and -u, which is an unscaled
68 number of processes.
69
70 Exit Status:
71 Returns success unless an invalid option is supplied or an error occurs.
72 $END
73
74 #if !defined (_MINIX)
75
76 #include <config.h>
77
78 #include "../bashtypes.h"
79 #if defined (HAVE_SYS_PARAM_H)
80 # include <sys/param.h>
81 #endif
82
83 #if defined (HAVE_UNISTD_H)
84 # include <unistd.h>
85 #endif
86
87 #include <stdio.h>
88 #include <errno.h>
89
90 #include "../bashintl.h"
91
92 #include "../shell.h"
93 #include "common.h"
94 #include "bashgetopt.h"
95 #include "pipesize.h"
96
97 #if !defined (errno)
98 extern int errno;
99 #endif
100
101 /* For some reason, HPUX chose to make these definitions visible only if
102 _KERNEL is defined, so we define _KERNEL before including <sys/resource.h>
103 and #undef it afterward. */
104 #if defined (HAVE_RESOURCE)
105 # include <sys/time.h>
106 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
107 # define _KERNEL
108 # endif
109 # include <sys/resource.h>
110 # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL)
111 # undef _KERNEL
112 # endif
113 #elif defined (HAVE_SYS_TIMES_H)
114 # include <sys/times.h>
115 #endif
116
117 #if defined (HAVE_LIMITS_H)
118 # include <limits.h>
119 #endif
120
121 /* Check for the most basic symbols. If they aren't present, this
122 system's <sys/resource.h> isn't very useful to us. */
123 #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT)
124 # undef HAVE_RESOURCE
125 #endif
126
127 #if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H)
128 # include <ulimit.h>
129 #endif
130
131 #if !defined (RLIMTYPE)
132 # define RLIMTYPE long
133 # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
134 # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
135 #endif
136
137 /* Alternate names */
138
139 /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */
140 #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
141 # define RLIMIT_NOFILE RLIMIT_OFILE
142 #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */
143
144 #if defined (HAVE_RESOURCE) && defined (RLIMIT_POSIXLOCKS) && !defined (RLIMIT_LOCKS)
145 # define RLIMIT_LOCKS RLIMIT_POSIXLOCKS
146 #endif /* HAVE_RESOURCE && RLIMIT_POSIXLOCKS && !RLIMIT_LOCKS */
147
148 /* Some systems have these, some do not. */
149 #ifdef RLIMIT_FSIZE
150 # define RLIMIT_FILESIZE RLIMIT_FSIZE
151 #else
152 # define RLIMIT_FILESIZE 256
153 #endif
154
155 #define RLIMIT_PIPESIZE 257
156
157 #ifdef RLIMIT_NOFILE
158 # define RLIMIT_OPENFILES RLIMIT_NOFILE
159 #else
160 # define RLIMIT_OPENFILES 258
161 #endif
162
163 #ifdef RLIMIT_VMEM
164 # define RLIMIT_VIRTMEM RLIMIT_VMEM
165 # define RLIMIT_VMBLKSZ 1024
166 #else
167 # ifdef RLIMIT_AS
168 # define RLIMIT_VIRTMEM RLIMIT_AS
169 # define RLIMIT_VMBLKSZ 1024
170 # else
171 # define RLIMIT_VIRTMEM 259
172 # define RLIMIT_VMBLKSZ 1
173 # endif
174 #endif
175
176 #ifdef RLIMIT_NPROC
177 # define RLIMIT_MAXUPROC RLIMIT_NPROC
178 #else
179 # define RLIMIT_MAXUPROC 260
180 #endif
181
182 #if !defined (RLIMIT_PTHREAD) && defined (RLIMIT_NTHR)
183 # define RLIMIT_PTHREAD RLIMIT_NTHR
184 #endif
185
186 #if !defined (RLIM_INFINITY)
187 # define RLIM_INFINITY 0x7fffffff
188 #endif
189
190 #if !defined (RLIM_SAVED_CUR)
191 # define RLIM_SAVED_CUR RLIM_INFINITY
192 #endif
193
194 #if !defined (RLIM_SAVED_MAX)
195 # define RLIM_SAVED_MAX RLIM_INFINITY
196 #endif
197
198 #define LIMIT_HARD 0x01
199 #define LIMIT_SOFT 0x02
200
201 /* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes
202 otherwise. */
203 #define POSIXBLK -2
204
205 #define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x))
206
207 static int _findlim PARAMS((int));
208
209 static int ulimit_internal PARAMS((int, char *, int, int));
210
211 static int get_limit PARAMS((int, RLIMTYPE *, RLIMTYPE *));
212 static int set_limit PARAMS((int, RLIMTYPE, int));
213
214 static void printone PARAMS((int, RLIMTYPE, int));
215 static void print_all_limits PARAMS((int));
216
217 static int set_all_limits PARAMS((int, RLIMTYPE));
218
219 static int filesize PARAMS((RLIMTYPE *));
220 static int pipesize PARAMS((RLIMTYPE *));
221 static int getmaxuprc PARAMS((RLIMTYPE *));
222 static int getmaxvm PARAMS((RLIMTYPE *, RLIMTYPE *));
223
224 typedef struct {
225 int option; /* The ulimit option for this limit. */
226 int parameter; /* Parameter to pass to get_limit (). */
227 int block_factor; /* Blocking factor for specific limit. */
228 const char * const description; /* Descriptive string to output. */
229 const char * const units; /* scale */
230 } RESOURCE_LIMITS;
231
232 static RESOURCE_LIMITS limits[] = {
233 #ifdef RLIMIT_NPTS
234 { 'P', RLIMIT_NPTS, 1, "number of pseudoterminals", (char *)NULL },
235 #endif
236 #ifdef RLIMIT_RTTIME
237 { 'R', RLIMIT_RTTIME, 1, "real-time non-blocking time", "microseconds" },
238 #endif
239 #ifdef RLIMIT_PTHREAD
240 { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL },
241 #endif
242 #ifdef RLIMIT_SBSIZE
243 { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" },
244 #endif
245 #ifdef RLIMIT_CORE
246 { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" },
247 #endif
248 #ifdef RLIMIT_DATA
249 { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
250 #endif
251 #ifdef RLIMIT_NICE
252 { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
253 #endif
254 { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" },
255 #ifdef RLIMIT_SIGPENDING
256 { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL },
257 #endif
258 #ifdef RLIMIT_KQUEUES
259 { 'k', RLIMIT_KQUEUES, 1, "max kqueues", (char *)NULL },
260 #endif
261 #ifdef RLIMIT_MEMLOCK
262 { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" },
263 #endif
264 #ifdef RLIMIT_RSS
265 { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" },
266 #endif /* RLIMIT_RSS */
267 { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL},
268 { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" },
269 #ifdef RLIMIT_MSGQUEUE
270 { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
271 #endif
272 #ifdef RLIMIT_RTPRIO
273 { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
274 #endif
275 #ifdef RLIMIT_STACK
276 { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
277 #endif
278 #ifdef RLIMIT_CPU
279 { 't', RLIMIT_CPU, 1, "cpu time", "seconds" },
280 #endif /* RLIMIT_CPU */
281 { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL },
282 #if defined (HAVE_RESOURCE)
283 { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" },
284 #endif
285 #ifdef RLIMIT_SWAP
286 { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" },
287 #endif
288 #ifdef RLIMIT_LOCKS
289 { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL },
290 #endif
291 { -1, -1, -1, (char *)NULL, (char *)NULL }
292 };
293 #define NCMDS (sizeof(limits) / sizeof(limits[0]))
294
295 typedef struct _cmd {
296 int cmd;
297 char *arg;
298 } ULCMD;
299
300 static ULCMD *cmdlist;
301 static int ncmd;
302 static int cmdlistsz;
303
304 #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT)
305 long
306 ulimit (cmd, newlim)
307 int cmd;
308 long newlim;
309 {
310 errno = EINVAL;
311 return -1;
312 }
313 #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */
314
315 static int
316 _findlim (opt)
317 int opt;
318 {
319 register int i;
320
321 for (i = 0; limits[i].option > 0; i++)
322 if (limits[i].option == opt)
323 return i;
324 return -1;
325 }
326
327 static char optstring[4 + 2 * NCMDS];
328
329 /* Report or set limits associated with certain per-process resources.
330 See the help documentation in builtins.c for a full description. */
331 int
332 ulimit_builtin (list)
333 register WORD_LIST *list;
334 {
335 register char *s;
336 int c, limind, mode, opt, all_limits;
337
338 mode = 0;
339
340 all_limits = 0;
341
342 /* Idea stolen from pdksh -- build option string the first time called. */
343 if (optstring[0] == 0)
344 {
345 s = optstring;
346 *s++ = 'a'; *s++ = 'S'; *s++ = 'H';
347 for (c = 0; limits[c].option > 0; c++)
348 {
349 *s++ = limits[c].option;
350 *s++ = ';';
351 }
352 *s = '\0';
353 }
354
355 /* Initialize the command list. */
356 if (cmdlistsz == 0)
357 cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD));
358 ncmd = 0;
359
360 reset_internal_getopt ();
361 while ((opt = internal_getopt (list, optstring)) != -1)
362 {
363 switch (opt)
364 {
365 case 'a':
366 all_limits++;
367 break;
368
369 /* -S and -H are modifiers, not real options. */
370 case 'S':
371 mode |= LIMIT_SOFT;
372 break;
373
374 case 'H':
375 mode |= LIMIT_HARD;
376 break;
377
378 CASE_HELPOPT;
379 case '?':
380 builtin_usage ();
381 return (EX_USAGE);
382
383 default:
384 if (ncmd >= cmdlistsz)
385 cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD));
386 cmdlist[ncmd].cmd = opt;
387 cmdlist[ncmd++].arg = list_optarg;
388 break;
389 }
390 }
391 list = loptend;
392
393 if (all_limits)
394 {
395 #ifdef NOTYET
396 if (list) /* setting */
397 {
398 if (STREQ (list->word->word, "unlimited") == 0)
399 {
400 builtin_error (_("%s: invalid limit argument"), list->word->word);
401 return (EXECUTION_FAILURE);
402 }
403 return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY));
404 }
405 #endif
406 print_all_limits (mode == 0 ? LIMIT_SOFT : mode);
407 return (sh_chkwrite (EXECUTION_SUCCESS));
408 }
409
410 /* default is `ulimit -f' */
411 if (ncmd == 0)
412 {
413 cmdlist[ncmd].cmd = 'f';
414 /* `ulimit something' is same as `ulimit -f something' */
415 cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL;
416 if (list)
417 list = list->next;
418 }
419
420 /* verify each command in the list. */
421 for (c = 0; c < ncmd; c++)
422 {
423 limind = _findlim (cmdlist[c].cmd);
424 if (limind == -1)
425 {
426 builtin_error (_("`%c': bad command"), cmdlist[c].cmd);
427 return (EX_USAGE);
428 }
429 }
430
431 for (c = 0; c < ncmd; c++)
432 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
433 return (EXECUTION_FAILURE);
434
435 return (EXECUTION_SUCCESS);
436 }
437
438 static int
439 ulimit_internal (cmd, cmdarg, mode, multiple)
440 int cmd;
441 char *cmdarg;
442 int mode, multiple;
443 {
444 int opt, limind, setting;
445 int block_factor;
446 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
447
448 setting = cmdarg != 0;
449 limind = _findlim (cmd);
450 if (mode == 0)
451 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
452 opt = get_limit (limind, &soft_limit, &hard_limit);
453 if (opt < 0)
454 {
455 builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
456 strerror (errno));
457 return (EXECUTION_FAILURE);
458 }
459
460 if (setting == 0) /* print the value of the specified limit */
461 {
462 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
463 return (EXECUTION_SUCCESS);
464 }
465
466 /* Setting the limit. */
467 if (STREQ (cmdarg, "hard"))
468 real_limit = hard_limit;
469 else if (STREQ (cmdarg, "soft"))
470 real_limit = soft_limit;
471 else if (STREQ (cmdarg, "unlimited"))
472 real_limit = RLIM_INFINITY;
473 else if (all_digits (cmdarg))
474 {
475 limit = string_to_rlimtype (cmdarg);
476 block_factor = BLOCKSIZE(limits[limind].block_factor);
477 real_limit = limit * block_factor;
478
479 if ((real_limit / block_factor) != limit)
480 {
481 sh_erange (cmdarg, _("limit"));
482 return (EXECUTION_FAILURE);
483 }
484 }
485 else
486 {
487 sh_invalidnum (cmdarg);
488 return (EXECUTION_FAILURE);
489 }
490
491 if (set_limit (limind, real_limit, mode) < 0)
492 {
493 builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
494 strerror (errno));
495 return (EXECUTION_FAILURE);
496 }
497
498 return (EXECUTION_SUCCESS);
499 }
500
501 static int
502 get_limit (ind, softlim, hardlim)
503 int ind;
504 RLIMTYPE *softlim, *hardlim;
505 {
506 RLIMTYPE value;
507 #if defined (HAVE_RESOURCE)
508 struct rlimit limit;
509 #endif
510
511 if (limits[ind].parameter >= 256)
512 {
513 switch (limits[ind].parameter)
514 {
515 case RLIMIT_FILESIZE:
516 if (filesize (&value) < 0)
517 return -1;
518 break;
519 case RLIMIT_PIPESIZE:
520 if (pipesize (&value) < 0)
521 return -1;
522 break;
523 case RLIMIT_OPENFILES:
524 value = (RLIMTYPE)getdtablesize ();
525 break;
526 case RLIMIT_VIRTMEM:
527 return (getmaxvm (softlim, hardlim));
528 case RLIMIT_MAXUPROC:
529 if (getmaxuprc (&value) < 0)
530 return -1;
531 break;
532 default:
533 errno = EINVAL;
534 return -1;
535 }
536 *softlim = *hardlim = value;
537 return (0);
538 }
539 else
540 {
541 #if defined (HAVE_RESOURCE)
542 if (getrlimit (limits[ind].parameter, &limit) < 0)
543 return -1;
544 *softlim = limit.rlim_cur;
545 *hardlim = limit.rlim_max;
546 # if defined (HPUX9)
547 if (limits[ind].parameter == RLIMIT_FILESIZE)
548 {
549 *softlim *= 512;
550 *hardlim *= 512; /* Ugh. */
551 }
552 else
553 # endif /* HPUX9 */
554 return 0;
555 #else
556 errno = EINVAL;
557 return -1;
558 #endif
559 }
560 }
561
562 static int
563 set_limit (ind, newlim, mode)
564 int ind;
565 RLIMTYPE newlim;
566 int mode;
567 {
568 #if defined (HAVE_RESOURCE)
569 struct rlimit limit;
570 RLIMTYPE val;
571 #endif
572
573 if (limits[ind].parameter >= 256)
574 switch (limits[ind].parameter)
575 {
576 case RLIMIT_FILESIZE:
577 #if !defined (HAVE_RESOURCE)
578 return (ulimit (2, newlim / 512L));
579 #else
580 errno = EINVAL;
581 return -1;
582 #endif
583
584 case RLIMIT_OPENFILES:
585 #if defined (HAVE_SETDTABLESIZE)
586 # if defined (__CYGWIN__)
587 /* Grrr... Cygwin declares setdtablesize as void. */
588 setdtablesize (newlim);
589 return 0;
590 # else
591 return (setdtablesize (newlim));
592 # endif
593 #endif
594 case RLIMIT_PIPESIZE:
595 case RLIMIT_VIRTMEM:
596 case RLIMIT_MAXUPROC:
597 default:
598 errno = EINVAL;
599 return -1;
600 }
601 else
602 {
603 #if defined (HAVE_RESOURCE)
604 if (getrlimit (limits[ind].parameter, &limit) < 0)
605 return -1;
606 # if defined (HPUX9)
607 if (limits[ind].parameter == RLIMIT_FILESIZE)
608 newlim /= 512; /* Ugh. */
609 # endif /* HPUX9 */
610 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
611 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
612 (limit.rlim_cur <= limit.rlim_max))
613 ? limit.rlim_max : newlim;
614 if (mode & LIMIT_SOFT)
615 limit.rlim_cur = val;
616 if (mode & LIMIT_HARD)
617 limit.rlim_max = val;
618
619 return (setrlimit (limits[ind].parameter, &limit));
620 #else
621 errno = EINVAL;
622 return -1;
623 #endif
624 }
625 }
626
627 static int
628 getmaxvm (softlim, hardlim)
629 RLIMTYPE *softlim, *hardlim;
630 {
631 #if defined (HAVE_RESOURCE)
632 struct rlimit datalim, stacklim;
633
634 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
635 return -1;
636
637 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
638 return -1;
639
640 /* Protect against overflow. */
641 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
642 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
643 return 0;
644 #else
645 errno = EINVAL;
646 return -1;
647 #endif /* HAVE_RESOURCE */
648 }
649
650 static int
651 filesize(valuep)
652 RLIMTYPE *valuep;
653 {
654 #if !defined (HAVE_RESOURCE)
655 long result;
656 if ((result = ulimit (1, 0L)) < 0)
657 return -1;
658 else
659 *valuep = (RLIMTYPE) result * 512;
660 return 0;
661 #else
662 errno = EINVAL;
663 return -1;
664 #endif
665 }
666
667 static int
668 pipesize (valuep)
669 RLIMTYPE *valuep;
670 {
671 #if defined (PIPE_BUF)
672 /* This is defined on Posix systems. */
673 *valuep = (RLIMTYPE) PIPE_BUF;
674 return 0;
675 #else
676 # if defined (_POSIX_PIPE_BUF)
677 *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
678 return 0;
679 # else
680 # if defined (PIPESIZE)
681 /* This is defined by running a program from the Makefile. */
682 *valuep = (RLIMTYPE) PIPESIZE;
683 return 0;
684 # else
685 errno = EINVAL;
686 return -1;
687 # endif /* PIPESIZE */
688 # endif /* _POSIX_PIPE_BUF */
689 #endif /* PIPE_BUF */
690 }
691
692 static int
693 getmaxuprc (valuep)
694 RLIMTYPE *valuep;
695 {
696 long maxchild;
697
698 maxchild = getmaxchild ();
699 if (maxchild < 0)
700 {
701 errno = EINVAL;
702 return -1;
703 }
704 else
705 {
706 *valuep = (RLIMTYPE) maxchild;
707 return 0;
708 }
709 }
710
711 static void
712 print_all_limits (mode)
713 int mode;
714 {
715 register int i;
716 RLIMTYPE softlim, hardlim;
717
718 if (mode == 0)
719 mode |= LIMIT_SOFT;
720
721 for (i = 0; limits[i].option > 0; i++)
722 {
723 if (get_limit (i, &softlim, &hardlim) == 0)
724 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
725 else if (errno != EINVAL)
726 builtin_error ("%s: cannot get limit: %s", limits[i].description,
727 strerror (errno));
728 }
729 }
730
731 static void
732 printone (limind, curlim, pdesc)
733 int limind;
734 RLIMTYPE curlim;
735 int pdesc;
736 {
737 char unitstr[64];
738 int factor;
739
740 factor = BLOCKSIZE(limits[limind].block_factor);
741 if (pdesc)
742 {
743 if (limits[limind].units)
744 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
745 else
746 sprintf (unitstr, "(-%c) ", limits[limind].option);
747
748 printf ("%-20s %20s", limits[limind].description, unitstr);
749 }
750 if (curlim == RLIM_INFINITY)
751 puts ("unlimited");
752 else if (curlim == RLIM_SAVED_MAX)
753 puts ("hard");
754 else if (curlim == RLIM_SAVED_CUR)
755 puts ("soft");
756 else
757 print_rlimtype ((curlim / factor), 1);
758 }
759
760 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
761 causes all limits to be set as high as possible depending on mode (like
762 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
763 were set successfully, and 1 if at least one limit could not be set.
764
765 To raise all soft limits to their corresponding hard limits, use
766 ulimit -S -a unlimited
767 To attempt to raise all hard limits to infinity (superuser-only), use
768 ulimit -H -a unlimited
769 To attempt to raise all soft and hard limits to infinity, use
770 ulimit -a unlimited
771 */
772
773 static int
774 set_all_limits (mode, newlim)
775 int mode;
776 RLIMTYPE newlim;
777 {
778 register int i;
779 int retval = 0;
780
781 if (newlim != RLIM_INFINITY)
782 {
783 errno = EINVAL;
784 return -1;
785 }
786
787 if (mode == 0)
788 mode = LIMIT_SOFT|LIMIT_HARD;
789
790 for (retval = i = 0; limits[i].option > 0; i++)
791 if (set_limit (i, newlim, mode) < 0)
792 {
793 builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,
794 strerror (errno));
795 retval = 1;
796 }
797 return retval;
798 }
799
800 #endif /* !_MINIX */