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