~ubuntu-branches/ubuntu/warty/bash/warty

« back to all changes in this revision

Viewing changes to builtins/ulimit.def

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2002-04-08 20:51:41 UTC
  • Revision ID: james.westby@ubuntu.com-20020408205141-qovkhu3a90201hf2
Tags: upstream-2.05a
ImportĀ upstreamĀ versionĀ 2.05a

Show diffs side-by-side

added added

removed removed

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