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