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