| This file is ulimit.def, from which is created ulimit.c. |
| It implements the builtin "ulimit" in Bash. |
| |
| Copyright (C) 1987-2010 Free Software Foundation, Inc. |
| |
| This file is part of GNU Bash, the Bourne Again SHell. |
| |
| Bash is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| Bash is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with Bash. If not, see <http://www.gnu.org/licenses/>. |
| |
| $PRODUCES ulimit.c |
| |
| $BUILTIN ulimit |
| $FUNCTION ulimit_builtin |
| $DEPENDS_ON !_MINIX |
| $SHORT_DOC ulimit [-SHacdefilmnpqrstuvx] [limit] |
| Modify shell resource limits. |
| |
| Provides control over the resources available to the shell and processes |
| it creates, on systems that allow such control. |
| |
| Options: |
| -S use the `soft' resource limit |
| -H use the `hard' resource limit |
| -a all current limits are reported |
| -b the socket buffer size |
| -c the maximum size of core files created |
| -d the maximum size of a process's data segment |
| -e the maximum scheduling priority (`nice') |
| -f the maximum size of files written by the shell and its children |
| -i the maximum number of pending signals |
| -l the maximum size a process may lock into memory |
| -m the maximum resident set size |
| -n the maximum number of open file descriptors |
| -p the pipe buffer size |
| -q the maximum number of bytes in POSIX message queues |
| -r the maximum real-time scheduling priority |
| -s the maximum stack size |
| -t the maximum amount of cpu time in seconds |
| -u the maximum number of user processes |
| -v the size of virtual memory |
| -x the maximum number of file locks |
| |
| If LIMIT is given, it is the new value of the specified resource; the |
| special LIMIT values `soft', `hard', and `unlimited' stand for the |
| current soft limit, the current hard limit, and no limit, respectively. |
| Otherwise, the current value of the specified resource is printed. If |
| no option is given, then -f is assumed. |
| |
| Values are in 1024-byte increments, except for -t, which is in seconds, |
| -p, which is in increments of 512 bytes, and -u, which is an unscaled |
| number of processes. |
| |
| Exit Status: |
| Returns success unless an invalid option is supplied or an error occurs. |
| $END |
| |
| #if !defined (_MINIX) |
| |
| #include <config.h> |
| |
| #include "../bashtypes.h" |
| #ifndef _MINIX |
| # include <sys/param.h> |
| #endif |
| |
| #if defined (HAVE_UNISTD_H) |
| # include <unistd.h> |
| #endif |
| |
| #include <stdio.h> |
| #include <errno.h> |
| |
| #include "../bashintl.h" |
| |
| #include "../shell.h" |
| #include "common.h" |
| #include "bashgetopt.h" |
| #include "pipesize.h" |
| |
| #if !defined (errno) |
| extern int errno; |
| #endif |
| |
| /* For some reason, HPUX chose to make these definitions visible only if |
| _KERNEL is defined, so we define _KERNEL before including <sys/resource.h> |
| and #undef it afterward. */ |
| #if defined (HAVE_RESOURCE) |
| # include <sys/time.h> |
| # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) |
| # define _KERNEL |
| # endif |
| # include <sys/resource.h> |
| # if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) |
| # undef _KERNEL |
| # endif |
| #elif defined (HAVE_SYS_TIMES_H) |
| # include <sys/times.h> |
| #endif |
| |
| #if defined (HAVE_LIMITS_H) |
| # include <limits.h> |
| #endif |
| |
| /* Check for the most basic symbols. If they aren't present, this |
| system's <sys/resource.h> isn't very useful to us. */ |
| #if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT) |
| # undef HAVE_RESOURCE |
| #endif |
| |
| #if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H) |
| # include <ulimit.h> |
| #endif |
| |
| #if !defined (RLIMTYPE) |
| # define RLIMTYPE long |
| # define string_to_rlimtype(s) strtol(s, (char **)NULL, 10) |
| # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "") |
| #endif |
| |
| /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */ |
| #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) |
| # define RLIMIT_NOFILE RLIMIT_OFILE |
| #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */ |
| |
| /* Some systems have these, some do not. */ |
| #ifdef RLIMIT_FSIZE |
| # define RLIMIT_FILESIZE RLIMIT_FSIZE |
| #else |
| # define RLIMIT_FILESIZE 256 |
| #endif |
| |
| #define RLIMIT_PIPESIZE 257 |
| |
| #ifdef RLIMIT_NOFILE |
| # define RLIMIT_OPENFILES RLIMIT_NOFILE |
| #else |
| # define RLIMIT_OPENFILES 258 |
| #endif |
| |
| #ifdef RLIMIT_VMEM |
| # define RLIMIT_VIRTMEM RLIMIT_VMEM |
| # define RLIMIT_VMBLKSZ 1024 |
| #else |
| # ifdef RLIMIT_AS |
| # define RLIMIT_VIRTMEM RLIMIT_AS |
| # define RLIMIT_VMBLKSZ 1024 |
| # else |
| # define RLIMIT_VIRTMEM 259 |
| # define RLIMIT_VMBLKSZ 1 |
| # endif |
| #endif |
| |
| #ifdef RLIMIT_NPROC |
| # define RLIMIT_MAXUPROC RLIMIT_NPROC |
| #else |
| # define RLIMIT_MAXUPROC 260 |
| #endif |
| |
| #if !defined (RLIM_INFINITY) |
| # define RLIM_INFINITY 0x7fffffff |
| #endif |
| |
| #if !defined (RLIM_SAVED_CUR) |
| # define RLIM_SAVED_CUR RLIM_INFINITY |
| #endif |
| |
| #if !defined (RLIM_SAVED_MAX) |
| # define RLIM_SAVED_MAX RLIM_INFINITY |
| #endif |
| |
| #define LIMIT_HARD 0x01 |
| #define LIMIT_SOFT 0x02 |
| |
| /* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes |
| otherwise. */ |
| #define POSIXBLK -2 |
| |
| #define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x)) |
| |
| extern int posixly_correct; |
| |
| static int _findlim __P((int)); |
| |
| static int ulimit_internal __P((int, char *, int, int)); |
| |
| static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *)); |
| static int set_limit __P((int, RLIMTYPE, int)); |
| |
| static void printone __P((int, RLIMTYPE, int)); |
| static void print_all_limits __P((int)); |
| |
| static int set_all_limits __P((int, RLIMTYPE)); |
| |
| static int filesize __P((RLIMTYPE *)); |
| static int pipesize __P((RLIMTYPE *)); |
| static int getmaxuprc __P((RLIMTYPE *)); |
| static int getmaxvm __P((RLIMTYPE *, RLIMTYPE *)); |
| |
| typedef struct { |
| int option; /* The ulimit option for this limit. */ |
| int parameter; /* Parameter to pass to get_limit (). */ |
| int block_factor; /* Blocking factor for specific limit. */ |
| const char * const description; /* Descriptive string to output. */ |
| const char * const units; /* scale */ |
| } RESOURCE_LIMITS; |
| |
| static RESOURCE_LIMITS limits[] = { |
| #ifdef RLIMIT_PTHREAD |
| { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL }, |
| #endif |
| #ifdef RLIMIT_SBSIZE |
| { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" }, |
| #endif |
| #ifdef RLIMIT_CORE |
| { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" }, |
| #endif |
| #ifdef RLIMIT_DATA |
| { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" }, |
| #endif |
| #ifdef RLIMIT_NICE |
| { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL }, |
| #endif |
| { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" }, |
| #ifdef RLIMIT_SIGPENDING |
| { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL }, |
| #endif |
| #ifdef RLIMIT_MEMLOCK |
| { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" }, |
| #endif |
| #ifdef RLIMIT_RSS |
| { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" }, |
| #endif /* RLIMIT_RSS */ |
| { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL}, |
| { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" }, |
| #ifdef RLIMIT_MSGQUEUE |
| { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" }, |
| #endif |
| #ifdef RLIMIT_RTPRIO |
| { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL }, |
| #endif |
| #ifdef RLIMIT_STACK |
| { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" }, |
| #endif |
| #ifdef RLIMIT_CPU |
| { 't', RLIMIT_CPU, 1, "cpu time", "seconds" }, |
| #endif /* RLIMIT_CPU */ |
| { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL }, |
| #if defined (HAVE_RESOURCE) |
| { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" }, |
| #endif |
| #ifdef RLIMIT_SWAP |
| { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" }, |
| #endif |
| #ifdef RLIMIT_LOCKS |
| { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL }, |
| #endif |
| { -1, -1, -1, (char *)NULL, (char *)NULL } |
| }; |
| #define NCMDS (sizeof(limits) / sizeof(limits[0])) |
| |
| typedef struct _cmd { |
| int cmd; |
| char *arg; |
| } ULCMD; |
| |
| static ULCMD *cmdlist; |
| static int ncmd; |
| static int cmdlistsz; |
| |
| #if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT) |
| long |
| ulimit (cmd, newlim) |
| int cmd; |
| long newlim; |
| { |
| errno = EINVAL; |
| return -1; |
| } |
| #endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */ |
| |
| static int |
| _findlim (opt) |
| int opt; |
| { |
| register int i; |
| |
| for (i = 0; limits[i].option > 0; i++) |
| if (limits[i].option == opt) |
| return i; |
| return -1; |
| } |
| |
| static char optstring[4 + 2 * NCMDS]; |
| |
| /* Report or set limits associated with certain per-process resources. |
| See the help documentation in builtins.c for a full description. */ |
| int |
| ulimit_builtin (list) |
| register WORD_LIST *list; |
| { |
| register char *s; |
| int c, limind, mode, opt, all_limits; |
| |
| mode = 0; |
| |
| all_limits = 0; |
| |
| /* Idea stolen from pdksh -- build option string the first time called. */ |
| if (optstring[0] == 0) |
| { |
| s = optstring; |
| *s++ = 'a'; *s++ = 'S'; *s++ = 'H'; |
| for (c = 0; limits[c].option > 0; c++) |
| { |
| *s++ = limits[c].option; |
| *s++ = ';'; |
| } |
| *s = '\0'; |
| } |
| |
| /* Initialize the command list. */ |
| if (cmdlistsz == 0) |
| cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD)); |
| ncmd = 0; |
| |
| reset_internal_getopt (); |
| while ((opt = internal_getopt (list, optstring)) != -1) |
| { |
| switch (opt) |
| { |
| case 'a': |
| all_limits++; |
| break; |
| |
| /* -S and -H are modifiers, not real options. */ |
| case 'S': |
| mode |= LIMIT_SOFT; |
| break; |
| |
| case 'H': |
| mode |= LIMIT_HARD; |
| break; |
| |
| case '?': |
| builtin_usage (); |
| return (EX_USAGE); |
| |
| default: |
| if (ncmd >= cmdlistsz) |
| cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD)); |
| cmdlist[ncmd].cmd = opt; |
| cmdlist[ncmd++].arg = list_optarg; |
| break; |
| } |
| } |
| list = loptend; |
| |
| if (all_limits) |
| { |
| #ifdef NOTYET |
| if (list) /* setting */ |
| { |
| if (STREQ (list->word->word, "unlimited") == 0) |
| { |
| builtin_error (_("%s: invalid limit argument"), list->word->word); |
| return (EXECUTION_FAILURE); |
| } |
| return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY)); |
| } |
| #endif |
| print_all_limits (mode == 0 ? LIMIT_SOFT : mode); |
| return (sh_chkwrite (EXECUTION_SUCCESS)); |
| } |
| |
| /* default is `ulimit -f' */ |
| if (ncmd == 0) |
| { |
| cmdlist[ncmd].cmd = 'f'; |
| /* `ulimit something' is same as `ulimit -f something' */ |
| cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL; |
| if (list) |
| list = list->next; |
| } |
| |
| /* verify each command in the list. */ |
| for (c = 0; c < ncmd; c++) |
| { |
| limind = _findlim (cmdlist[c].cmd); |
| if (limind == -1) |
| { |
| builtin_error (_("`%c': bad command"), cmdlist[c].cmd); |
| return (EX_USAGE); |
| } |
| } |
| |
| for (c = 0; c < ncmd; c++) |
| if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE) |
| return (EXECUTION_FAILURE); |
| |
| return (EXECUTION_SUCCESS); |
| } |
| |
| static int |
| ulimit_internal (cmd, cmdarg, mode, multiple) |
| int cmd; |
| char *cmdarg; |
| int mode, multiple; |
| { |
| int opt, limind, setting; |
| int block_factor; |
| RLIMTYPE soft_limit, hard_limit, real_limit, limit; |
| |
| setting = cmdarg != 0; |
| limind = _findlim (cmd); |
| if (mode == 0) |
| mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT; |
| opt = get_limit (limind, &soft_limit, &hard_limit); |
| if (opt < 0) |
| { |
| builtin_error (_("%s: cannot get limit: %s"), limits[limind].description, |
| strerror (errno)); |
| return (EXECUTION_FAILURE); |
| } |
| |
| if (setting == 0) /* print the value of the specified limit */ |
| { |
| printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple); |
| return (EXECUTION_SUCCESS); |
| } |
| |
| /* Setting the limit. */ |
| if (STREQ (cmdarg, "hard")) |
| real_limit = hard_limit; |
| else if (STREQ (cmdarg, "soft")) |
| real_limit = soft_limit; |
| else if (STREQ (cmdarg, "unlimited")) |
| real_limit = RLIM_INFINITY; |
| else if (all_digits (cmdarg)) |
| { |
| limit = string_to_rlimtype (cmdarg); |
| block_factor = BLOCKSIZE(limits[limind].block_factor); |
| real_limit = limit * block_factor; |
| |
| if ((real_limit / block_factor) != limit) |
| { |
| sh_erange (cmdarg, _("limit")); |
| return (EXECUTION_FAILURE); |
| } |
| } |
| else |
| { |
| sh_invalidnum (cmdarg); |
| return (EXECUTION_FAILURE); |
| } |
| |
| if (set_limit (limind, real_limit, mode) < 0) |
| { |
| builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description, |
| strerror (errno)); |
| return (EXECUTION_FAILURE); |
| } |
| |
| return (EXECUTION_SUCCESS); |
| } |
| |
| static int |
| get_limit (ind, softlim, hardlim) |
| int ind; |
| RLIMTYPE *softlim, *hardlim; |
| { |
| RLIMTYPE value; |
| #if defined (HAVE_RESOURCE) |
| struct rlimit limit; |
| #endif |
| |
| if (limits[ind].parameter >= 256) |
| { |
| switch (limits[ind].parameter) |
| { |
| case RLIMIT_FILESIZE: |
| if (filesize (&value) < 0) |
| return -1; |
| break; |
| case RLIMIT_PIPESIZE: |
| if (pipesize (&value) < 0) |
| return -1; |
| break; |
| case RLIMIT_OPENFILES: |
| value = (RLIMTYPE)getdtablesize (); |
| break; |
| case RLIMIT_VIRTMEM: |
| return (getmaxvm (softlim, hardlim)); |
| case RLIMIT_MAXUPROC: |
| if (getmaxuprc (&value) < 0) |
| return -1; |
| break; |
| default: |
| errno = EINVAL; |
| return -1; |
| } |
| *softlim = *hardlim = value; |
| return (0); |
| } |
| else |
| { |
| #if defined (HAVE_RESOURCE) |
| if (getrlimit (limits[ind].parameter, &limit) < 0) |
| return -1; |
| *softlim = limit.rlim_cur; |
| *hardlim = limit.rlim_max; |
| # if defined (HPUX9) |
| if (limits[ind].parameter == RLIMIT_FILESIZE) |
| { |
| *softlim *= 512; |
| *hardlim *= 512; /* Ugh. */ |
| } |
| else |
| # endif /* HPUX9 */ |
| return 0; |
| #else |
| errno = EINVAL; |
| return -1; |
| #endif |
| } |
| } |
| |
| static int |
| set_limit (ind, newlim, mode) |
| int ind; |
| RLIMTYPE newlim; |
| int mode; |
| { |
| #if defined (HAVE_RESOURCE) |
| struct rlimit limit; |
| RLIMTYPE val; |
| #endif |
| |
| if (limits[ind].parameter >= 256) |
| switch (limits[ind].parameter) |
| { |
| case RLIMIT_FILESIZE: |
| #if !defined (HAVE_RESOURCE) |
| return (ulimit (2, newlim / 512L)); |
| #else |
| errno = EINVAL; |
| return -1; |
| #endif |
| |
| case RLIMIT_OPENFILES: |
| #if defined (HAVE_SETDTABLESIZE) |
| # if defined (__CYGWIN__) |
| /* Grrr... Cygwin declares setdtablesize as void. */ |
| setdtablesize (newlim); |
| return 0; |
| # else |
| return (setdtablesize (newlim)); |
| # endif |
| #endif |
| case RLIMIT_PIPESIZE: |
| case RLIMIT_VIRTMEM: |
| case RLIMIT_MAXUPROC: |
| default: |
| errno = EINVAL; |
| return -1; |
| } |
| else |
| { |
| #if defined (HAVE_RESOURCE) |
| if (getrlimit (limits[ind].parameter, &limit) < 0) |
| return -1; |
| # if defined (HPUX9) |
| if (limits[ind].parameter == RLIMIT_FILESIZE) |
| newlim /= 512; /* Ugh. */ |
| # endif /* HPUX9 */ |
| val = (current_user.euid != 0 && newlim == RLIM_INFINITY && |
| (mode & LIMIT_HARD) == 0 && /* XXX -- test */ |
| (limit.rlim_cur <= limit.rlim_max)) |
| ? limit.rlim_max : newlim; |
| if (mode & LIMIT_SOFT) |
| limit.rlim_cur = val; |
| if (mode & LIMIT_HARD) |
| limit.rlim_max = val; |
| |
| return (setrlimit (limits[ind].parameter, &limit)); |
| #else |
| errno = EINVAL; |
| return -1; |
| #endif |
| } |
| } |
| |
| static int |
| getmaxvm (softlim, hardlim) |
| RLIMTYPE *softlim, *hardlim; |
| { |
| #if defined (HAVE_RESOURCE) |
| struct rlimit datalim, stacklim; |
| |
| if (getrlimit (RLIMIT_DATA, &datalim) < 0) |
| return -1; |
| |
| if (getrlimit (RLIMIT_STACK, &stacklim) < 0) |
| return -1; |
| |
| /* Protect against overflow. */ |
| *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L); |
| *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L); |
| return 0; |
| #else |
| errno = EINVAL; |
| return -1; |
| #endif /* HAVE_RESOURCE */ |
| } |
| |
| static int |
| filesize(valuep) |
| RLIMTYPE *valuep; |
| { |
| #if !defined (HAVE_RESOURCE) |
| long result; |
| if ((result = ulimit (1, 0L)) < 0) |
| return -1; |
| else |
| *valuep = (RLIMTYPE) result * 512; |
| return 0; |
| #else |
| errno = EINVAL; |
| return -1; |
| #endif |
| } |
| |
| static int |
| pipesize (valuep) |
| RLIMTYPE *valuep; |
| { |
| #if defined (PIPE_BUF) |
| /* This is defined on Posix systems. */ |
| *valuep = (RLIMTYPE) PIPE_BUF; |
| return 0; |
| #else |
| # if defined (_POSIX_PIPE_BUF) |
| *valuep = (RLIMTYPE) _POSIX_PIPE_BUF; |
| return 0; |
| # else |
| # if defined (PIPESIZE) |
| /* This is defined by running a program from the Makefile. */ |
| *valuep = (RLIMTYPE) PIPESIZE; |
| return 0; |
| # else |
| errno = EINVAL; |
| return -1; |
| # endif /* PIPESIZE */ |
| # endif /* _POSIX_PIPE_BUF */ |
| #endif /* PIPE_BUF */ |
| } |
| |
| static int |
| getmaxuprc (valuep) |
| RLIMTYPE *valuep; |
| { |
| long maxchild; |
| |
| maxchild = getmaxchild (); |
| if (maxchild < 0) |
| { |
| errno = EINVAL; |
| return -1; |
| } |
| else |
| { |
| *valuep = (RLIMTYPE) maxchild; |
| return 0; |
| } |
| } |
| |
| static void |
| print_all_limits (mode) |
| int mode; |
| { |
| register int i; |
| RLIMTYPE softlim, hardlim; |
| |
| if (mode == 0) |
| mode |= LIMIT_SOFT; |
| |
| for (i = 0; limits[i].option > 0; i++) |
| { |
| if (get_limit (i, &softlim, &hardlim) == 0) |
| printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1); |
| else if (errno != EINVAL) |
| builtin_error ("%s: cannot get limit: %s", limits[i].description, |
| strerror (errno)); |
| } |
| } |
| |
| static void |
| printone (limind, curlim, pdesc) |
| int limind; |
| RLIMTYPE curlim; |
| int pdesc; |
| { |
| char unitstr[64]; |
| int factor; |
| |
| factor = BLOCKSIZE(limits[limind].block_factor); |
| if (pdesc) |
| { |
| if (limits[limind].units) |
| sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option); |
| else |
| sprintf (unitstr, "(-%c) ", limits[limind].option); |
| |
| printf ("%-20s %16s", limits[limind].description, unitstr); |
| } |
| if (curlim == RLIM_INFINITY) |
| puts ("unlimited"); |
| else if (curlim == RLIM_SAVED_MAX) |
| puts ("hard"); |
| else if (curlim == RLIM_SAVED_CUR) |
| puts ("soft"); |
| else |
| print_rlimtype ((curlim / factor), 1); |
| } |
| |
| /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which |
| causes all limits to be set as high as possible depending on mode (like |
| csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits |
| were set successfully, and 1 if at least one limit could not be set. |
| |
| To raise all soft limits to their corresponding hard limits, use |
| ulimit -S -a unlimited |
| To attempt to raise all hard limits to infinity (superuser-only), use |
| ulimit -H -a unlimited |
| To attempt to raise all soft and hard limits to infinity, use |
| ulimit -a unlimited |
| */ |
| |
| static int |
| set_all_limits (mode, newlim) |
| int mode; |
| RLIMTYPE newlim; |
| { |
| register int i; |
| int retval = 0; |
| |
| if (newlim != RLIM_INFINITY) |
| { |
| errno = EINVAL; |
| return -1; |
| } |
| |
| if (mode == 0) |
| mode = LIMIT_SOFT|LIMIT_HARD; |
| |
| for (retval = i = 0; limits[i].option > 0; i++) |
| if (set_limit (i, newlim, mode) < 0) |
| { |
| builtin_error (_("%s: cannot modify limit: %s"), limits[i].description, |
| strerror (errno)); |
| retval = 1; |
| } |
| return retval; |
| } |
| |
| #endif /* !_MINIX */ |