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