]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/ulimit.def
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[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-2021 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 [-SHabcdefiklmnpqrstuvxPRT] [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 /* POSIX compatibility. If the last item in cmdlist does not have an option
432 argument, but there is an operand (list != 0), treat the operand as if
433 it were an option argument for that last command. */
434 if (list && list->word && cmdlist[ncmd - 1].arg == 0)
435 {
436 cmdlist[ncmd - 1].arg = list->word->word;
437 list = list->next;
438 }
439
440 for (c = 0; c < ncmd; c++)
441 if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE)
442 return (EXECUTION_FAILURE);
443
444 return (EXECUTION_SUCCESS);
445 }
446
447 static int
448 ulimit_internal (cmd, cmdarg, mode, multiple)
449 int cmd;
450 char *cmdarg;
451 int mode, multiple;
452 {
453 int opt, limind, setting;
454 int block_factor;
455 RLIMTYPE soft_limit, hard_limit, real_limit, limit;
456
457 setting = cmdarg != 0;
458 limind = _findlim (cmd);
459 if (mode == 0)
460 mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT;
461 opt = get_limit (limind, &soft_limit, &hard_limit);
462 if (opt < 0)
463 {
464 builtin_error (_("%s: cannot get limit: %s"), limits[limind].description,
465 strerror (errno));
466 return (EXECUTION_FAILURE);
467 }
468
469 if (setting == 0) /* print the value of the specified limit */
470 {
471 printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple);
472 return (EXECUTION_SUCCESS);
473 }
474
475 /* Setting the limit. */
476 if (STREQ (cmdarg, "hard"))
477 real_limit = hard_limit;
478 else if (STREQ (cmdarg, "soft"))
479 real_limit = soft_limit;
480 else if (STREQ (cmdarg, "unlimited"))
481 real_limit = RLIM_INFINITY;
482 else if (all_digits (cmdarg))
483 {
484 limit = string_to_rlimtype (cmdarg);
485 block_factor = BLOCKSIZE(limits[limind].block_factor);
486 real_limit = limit * block_factor;
487
488 if ((real_limit / block_factor) != limit)
489 {
490 sh_erange (cmdarg, _("limit"));
491 return (EXECUTION_FAILURE);
492 }
493 }
494 else
495 {
496 sh_invalidnum (cmdarg);
497 return (EXECUTION_FAILURE);
498 }
499
500 if (set_limit (limind, real_limit, mode) < 0)
501 {
502 builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description,
503 strerror (errno));
504 return (EXECUTION_FAILURE);
505 }
506
507 return (EXECUTION_SUCCESS);
508 }
509
510 static int
511 get_limit (ind, softlim, hardlim)
512 int ind;
513 RLIMTYPE *softlim, *hardlim;
514 {
515 RLIMTYPE value;
516 #if defined (HAVE_RESOURCE)
517 struct rlimit limit;
518 #endif
519
520 if (limits[ind].parameter >= 256)
521 {
522 switch (limits[ind].parameter)
523 {
524 case RLIMIT_FILESIZE:
525 if (filesize (&value) < 0)
526 return -1;
527 break;
528 case RLIMIT_PIPESIZE:
529 if (pipesize (&value) < 0)
530 return -1;
531 break;
532 case RLIMIT_OPENFILES:
533 value = (RLIMTYPE)getdtablesize ();
534 break;
535 case RLIMIT_VIRTMEM:
536 return (getmaxvm (softlim, hardlim));
537 case RLIMIT_MAXUPROC:
538 if (getmaxuprc (&value) < 0)
539 return -1;
540 break;
541 default:
542 errno = EINVAL;
543 return -1;
544 }
545 *softlim = *hardlim = value;
546 return (0);
547 }
548 else
549 {
550 #if defined (HAVE_RESOURCE)
551 if (getrlimit (limits[ind].parameter, &limit) < 0)
552 return -1;
553 *softlim = limit.rlim_cur;
554 *hardlim = limit.rlim_max;
555 # if defined (HPUX9)
556 if (limits[ind].parameter == RLIMIT_FILESIZE)
557 {
558 *softlim *= 512;
559 *hardlim *= 512; /* Ugh. */
560 }
561 else
562 # endif /* HPUX9 */
563 return 0;
564 #else
565 errno = EINVAL;
566 return -1;
567 #endif
568 }
569 }
570
571 static int
572 set_limit (ind, newlim, mode)
573 int ind;
574 RLIMTYPE newlim;
575 int mode;
576 {
577 #if defined (HAVE_RESOURCE)
578 struct rlimit limit;
579 RLIMTYPE val;
580 #endif
581
582 if (limits[ind].parameter >= 256)
583 switch (limits[ind].parameter)
584 {
585 case RLIMIT_FILESIZE:
586 #if !defined (HAVE_RESOURCE)
587 return (ulimit (2, newlim / 512L));
588 #else
589 errno = EINVAL;
590 return -1;
591 #endif
592
593 case RLIMIT_OPENFILES:
594 #if defined (HAVE_SETDTABLESIZE)
595 # if defined (__CYGWIN__)
596 /* Grrr... Cygwin declares setdtablesize as void. */
597 setdtablesize (newlim);
598 return 0;
599 # else
600 return (setdtablesize (newlim));
601 # endif
602 #endif
603 case RLIMIT_PIPESIZE:
604 case RLIMIT_VIRTMEM:
605 case RLIMIT_MAXUPROC:
606 default:
607 errno = EINVAL;
608 return -1;
609 }
610 else
611 {
612 #if defined (HAVE_RESOURCE)
613 if (getrlimit (limits[ind].parameter, &limit) < 0)
614 return -1;
615 # if defined (HPUX9)
616 if (limits[ind].parameter == RLIMIT_FILESIZE)
617 newlim /= 512; /* Ugh. */
618 # endif /* HPUX9 */
619 val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
620 (mode & LIMIT_HARD) == 0 && /* XXX -- test */
621 (limit.rlim_cur <= limit.rlim_max))
622 ? limit.rlim_max : newlim;
623 if (mode & LIMIT_SOFT)
624 limit.rlim_cur = val;
625 if (mode & LIMIT_HARD)
626 limit.rlim_max = val;
627
628 return (setrlimit (limits[ind].parameter, &limit));
629 #else
630 errno = EINVAL;
631 return -1;
632 #endif
633 }
634 }
635
636 static int
637 getmaxvm (softlim, hardlim)
638 RLIMTYPE *softlim, *hardlim;
639 {
640 #if defined (HAVE_RESOURCE)
641 struct rlimit datalim, stacklim;
642
643 if (getrlimit (RLIMIT_DATA, &datalim) < 0)
644 return -1;
645
646 if (getrlimit (RLIMIT_STACK, &stacklim) < 0)
647 return -1;
648
649 /* Protect against overflow. */
650 *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L);
651 *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L);
652 return 0;
653 #else
654 errno = EINVAL;
655 return -1;
656 #endif /* HAVE_RESOURCE */
657 }
658
659 static int
660 filesize(valuep)
661 RLIMTYPE *valuep;
662 {
663 #if !defined (HAVE_RESOURCE)
664 long result;
665 if ((result = ulimit (1, 0L)) < 0)
666 return -1;
667 else
668 *valuep = (RLIMTYPE) result * 512;
669 return 0;
670 #else
671 errno = EINVAL;
672 return -1;
673 #endif
674 }
675
676 static int
677 pipesize (valuep)
678 RLIMTYPE *valuep;
679 {
680 #if defined (PIPE_BUF)
681 /* This is defined on Posix systems. */
682 *valuep = (RLIMTYPE) PIPE_BUF;
683 return 0;
684 #else
685 # if defined (_POSIX_PIPE_BUF)
686 *valuep = (RLIMTYPE) _POSIX_PIPE_BUF;
687 return 0;
688 # else
689 # if defined (PIPESIZE)
690 /* This is defined by running a program from the Makefile. */
691 *valuep = (RLIMTYPE) PIPESIZE;
692 return 0;
693 # else
694 errno = EINVAL;
695 return -1;
696 # endif /* PIPESIZE */
697 # endif /* _POSIX_PIPE_BUF */
698 #endif /* PIPE_BUF */
699 }
700
701 static int
702 getmaxuprc (valuep)
703 RLIMTYPE *valuep;
704 {
705 long maxchild;
706
707 maxchild = getmaxchild ();
708 if (maxchild < 0)
709 {
710 errno = EINVAL;
711 return -1;
712 }
713 else
714 {
715 *valuep = (RLIMTYPE) maxchild;
716 return 0;
717 }
718 }
719
720 static void
721 print_all_limits (mode)
722 int mode;
723 {
724 register int i;
725 RLIMTYPE softlim, hardlim;
726
727 if (mode == 0)
728 mode |= LIMIT_SOFT;
729
730 for (i = 0; limits[i].option > 0; i++)
731 {
732 if (get_limit (i, &softlim, &hardlim) == 0)
733 printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1);
734 else if (errno != EINVAL)
735 builtin_error ("%s: cannot get limit: %s", limits[i].description,
736 strerror (errno));
737 }
738 }
739
740 static void
741 printone (limind, curlim, pdesc)
742 int limind;
743 RLIMTYPE curlim;
744 int pdesc;
745 {
746 char unitstr[64];
747 int factor;
748
749 factor = BLOCKSIZE(limits[limind].block_factor);
750 if (pdesc)
751 {
752 if (limits[limind].units)
753 sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option);
754 else
755 sprintf (unitstr, "(-%c) ", limits[limind].option);
756
757 printf ("%-20s %20s", limits[limind].description, unitstr);
758 }
759 if (curlim == RLIM_INFINITY)
760 puts ("unlimited");
761 else if (curlim == RLIM_SAVED_MAX)
762 puts ("hard");
763 else if (curlim == RLIM_SAVED_CUR)
764 puts ("soft");
765 else
766 print_rlimtype ((curlim / factor), 1);
767 }
768
769 /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which
770 causes all limits to be set as high as possible depending on mode (like
771 csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits
772 were set successfully, and 1 if at least one limit could not be set.
773
774 To raise all soft limits to their corresponding hard limits, use
775 ulimit -S -a unlimited
776 To attempt to raise all hard limits to infinity (superuser-only), use
777 ulimit -H -a unlimited
778 To attempt to raise all soft and hard limits to infinity, use
779 ulimit -a unlimited
780 */
781
782 static int
783 set_all_limits (mode, newlim)
784 int mode;
785 RLIMTYPE newlim;
786 {
787 register int i;
788 int retval = 0;
789
790 if (newlim != RLIM_INFINITY)
791 {
792 errno = EINVAL;
793 return -1;
794 }
795
796 if (mode == 0)
797 mode = LIMIT_SOFT|LIMIT_HARD;
798
799 for (retval = i = 0; limits[i].option > 0; i++)
800 if (set_limit (i, newlim, mode) < 0)
801 {
802 builtin_error (_("%s: cannot modify limit: %s"), limits[i].description,
803 strerror (errno));
804 retval = 1;
805 }
806 return retval;
807 }
808
809 #endif /* !_MINIX */