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