Imported from ../bash-3.2.48.tar.gz.
[platform/upstream/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-2005 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 [-SHacdfilmnpqstuvx] [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   char *description;            /* Descriptive string to output. */
197   char *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 */