X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=builtins%2Fulimit.def;h=546dfd4f38ea77ec3bfd5fe963ca1ce93d0795c9;hb=ccc6cda312fea9f0468ee65b8f368e9653e1380b;hp=1947c367df6d5a736338e3bace4f4f5ed3a399ff;hpb=726f63884db0132f01745f1fb4465e6621088ccf;p=platform%2Fupstream%2Fbash.git diff --git a/builtins/ulimit.def b/builtins/ulimit.def index 1947c36..546dfd4 100644 --- a/builtins/ulimit.def +++ b/builtins/ulimit.def @@ -24,7 +24,7 @@ $PRODUCES ulimit.c $BUILTIN ulimit $FUNCTION ulimit_builtin $DEPENDS_ON !MINIX -$SHORT_DOC ulimit [-SHacdfmstpnuv [limit]] +$SHORT_DOC ulimit [-SHacdflmnpstuv] [limit] Ulimit provides control over the resources available to processes started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows: @@ -34,52 +34,68 @@ option is given, it is interpreted as follows: -a all current limits are reported -c the maximum size of core files created -d the maximum size of a process's data segment + -f the maximum size of files created by the shell + -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 -s the maximum stack size -t the maximum amount of cpu time in seconds - -f the maximum size of files created by the shell - -p the pipe buffer size - -n the maximum number of open file descriptors -u the maximum number of user processes -v the size of virtual memory If LIMIT is given, it is the new value of the specified resource. Otherwise, the current value of the specified resource is printed. -If no option is given, then -f is assumed. Values are in 1k +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. $END -#include -#include +#include + +#include "../bashtypes.h" #include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include #include + #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 + and #undef it afterward. */ #if defined (HAVE_RESOURCE) # include +# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) +# define _KERNEL +# endif # include +# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) +# undef _KERNEL +# endif #else # include #endif -#if defined (HAVE_UNISTD_H) -# include -#endif - #if defined (HAVE_LIMITS_H) # include #endif /* Check for the most basic symbols. If they aren't present, this system's isn't very useful to us. */ -#if !defined (RLIMIT_FSIZE) || defined (GETRLIMIT_MISSING) +#if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT) # undef HAVE_RESOURCE #endif @@ -89,509 +105,412 @@ extern int errno; # define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "") #endif -static void print_long (); +#define DESCFMT "%-28s" -/* **************************************************************** */ -/* */ -/* Ulimit builtin and Hacks. */ -/* */ -/* **************************************************************** */ +/* 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 */ -/* Block size for ulimit operations. */ -#define ULIMIT_BLOCK_SIZE ((long)1024) +/* 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 -#define u_FILE_SIZE 0x001 -#define u_MAX_BREAK_VAL 0x002 -#define u_PIPE_SIZE 0x004 -#define u_CORE_FILE_SIZE 0x008 -#define u_DATA_SEG_SIZE 0x010 -#define u_PHYS_MEM_SIZE 0x020 -#define u_CPU_TIME_LIMIT 0x040 -#define u_STACK_SIZE 0x080 -#define u_NUM_OPEN_FILES 0x100 -#define u_MAX_VIRTUAL_MEM 0x200 -#define u_MAX_USER_PROCS 0x400 +#ifdef RLIMIT_NOFILE +# define RLIMIT_OPENFILES RLIMIT_NOFILE +#else +# define RLIMIT_OPENFILES 258 +#endif -#define u_ALL_LIMITS 0x7ff +#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 +# define RLIM_INFINITY 0x7fffffff #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 */ +#if !defined (RLIM_INVALID) +# define RLIM_INVALID (RLIMTYPE)-1 +#endif #define LIMIT_HARD 0x01 #define LIMIT_SOFT 0x02 -static RLIMTYPE shell_ulimit (); +static int ulimit_internal (); +static void printone (); +static void print_all_limits (); + +static int get_limit (); +static int set_limit (); + +static RLIMTYPE filesize (); static RLIMTYPE pipesize (); -static RLIMTYPE open_files (); +static RLIMTYPE getmaxuprc (); +static RLIMTYPE getmaxvm (); + +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. */ + char *description; /* Descriptive string to output. */ +} RESOURCE_LIMITS; +static RESOURCE_LIMITS limits[] = { +#ifdef RLIMIT_CORE + { 'c', RLIMIT_CORE, 1024, "core file size (blocks)" }, +#endif +#ifdef RLIMIT_DATA + { 'd', RLIMIT_DATA, 1024, "data seg size (kbytes)" }, +#endif + { 'f', RLIMIT_FILESIZE, 1024, "file size (blocks)" }, +#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" }, + { 'p', RLIMIT_PIPESIZE, 512, "pipe size (512 bytes)" }, +#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" }, #if defined (HAVE_RESOURCE) -static RLIMTYPE getmaxvm (); -#endif /* HAVE_RESOURCE */ + { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory (kbytes)" }, +#endif + { -1, -1, -1, (char *)NULL } +}; +#define NCMDS (sizeof(limits) / sizeof(limits[0])) -static void print_specific_limits (); -static void print_all_limits (); +typedef struct _cmd { + int cmd; + char *arg; +} ULCMD; -static char t[2]; +static ULCMD *cmdlist; +static int ncmd; +static int cmdlistsz; -/* Return 1 if the limit associated with CMD can be raised from CURRENT - to NEW. This is for USG systems without HAVE_RESOURCE, most of which - do not allow any user other than root to raise limits. There are, - however, exceptions. */ -#if !defined (HAVE_RESOURCE) static int -canraise (cmd, current, new) - int cmd; - RLIMTYPE current, new; +_findlim (opt) + int opt; { -# if defined (HAVE_SETDTABLESIZE) - if (cmd == u_NUM_OPEN_FILES) - return (1); -# endif /* HAVE_SETDTABLSIZE */ + register int i; - return ((current > new) || (current_user.uid == 0)); + for (i = 0; limits[i].option > 0; i++) + if (limits[i].option == opt) + return i; + return -1; } -#endif /* !HAVE_RESOURCE */ -/* Report or set limits associated with certain per-process resources. - See the help documentation in builtins.c for a full description. +static char optstring[4 + 2 * NCMDS]; - Rewritten by Chet Ramey 6/30/91. */ +/* 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, setting, cmd, mode, verbose_print, opt_eof; - int all_limits, specific_limits; - long block_factor; - RLIMTYPE current_limit, real_limit, limit; + int c, limind, mode, opt, all_limits; - c = mode = verbose_print = opt_eof = 0; - limit = (RLIMTYPE)-1; + mode = 0; - do - { - cmd = setting = all_limits = specific_limits = 0; - block_factor = ULIMIT_BLOCK_SIZE; + all_limits = 0; - /* read_options: */ - if (list && !opt_eof && *list->word->word == '-') + /* 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 = &(list->word->word[1]); - list = list->next; - - while (*s && (c = *s++)) - { - switch (c) - { -#define ADD_CMD(x) { if (cmd) specific_limits++; cmd |= (x); } - - case '-': /* ulimit -- */ - opt_eof++; - break; - - case 'a': - all_limits++; - break; - - case 'f': - ADD_CMD (u_FILE_SIZE); - break; - -#if defined (HAVE_RESOURCE) - /* -S and -H are modifiers, not real options. */ - case 'S': - mode |= LIMIT_SOFT; - break; - - case 'H': - mode |= LIMIT_HARD; - break; - - case 'c': - ADD_CMD (u_CORE_FILE_SIZE); - break; - - case 'd': - ADD_CMD (u_DATA_SEG_SIZE); - break; - -#if !defined (USGr4) - case 'm': - ADD_CMD (u_PHYS_MEM_SIZE); - break; -#endif /* USGr4 */ - - case 't': - ADD_CMD (u_CPU_TIME_LIMIT); - block_factor = 1; /* seconds */ - break; - - case 's': - ADD_CMD (u_STACK_SIZE); - break; - - case 'v': - ADD_CMD (u_MAX_VIRTUAL_MEM); - block_factor = 1; - break; - - case 'u': - ADD_CMD (u_MAX_USER_PROCS); - block_factor = 1; - break; - -#endif /* HAVE_RESOURCE */ - - case 'p': - ADD_CMD (u_PIPE_SIZE); - block_factor = 512; - break; - - case 'n': - ADD_CMD (u_NUM_OPEN_FILES); - block_factor = 1; - break; - - default: /* error_case: */ - t[0] = c; - t[1] = '\0'; - bad_option (t); -#if !defined (HAVE_RESOURCE) - builtin_error("usage: ulimit [-afnp] [new limit]"); -#else - builtin_error("usage: ulimit [-SHacmdstfnpuv] [new limit]"); -#endif - return (EX_USAGE); - } - } + *s++ = limits[c].option; + *s++ = ';'; } + *s = '\0'; + } - if (all_limits) - { - print_all_limits (mode); - return (EXECUTION_SUCCESS); - } - - if (specific_limits) - { - print_specific_limits (cmd, mode); - if (list) - verbose_print++; - continue; - } - - if (cmd == 0) - cmd = u_FILE_SIZE; - - /* If an argument was supplied for the command, then we want to - set the limit. Note that `ulimit something' means a command - of -f with argument `something'. */ - if (list) - { - if (opt_eof || (*list->word->word != '-')) - { - s = list->word->word; - list = list->next; - - if (STREQ (s, "unlimited")) - limit = RLIM_INFINITY; - else if (all_digits (s)) - limit = string_to_rlimtype (s); - else - { - builtin_error ("bad non-numeric arg `%s'", s); - return (EXECUTION_FAILURE); - } - setting++; - } - else if (!opt_eof) - verbose_print++; - } - - if (limit == RLIM_INFINITY) - block_factor = 1; - - real_limit = limit * block_factor; - - /* If more than one option is given, list each in a verbose format, - the same that is used for -a. */ - if (!setting && verbose_print) + /* 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) { - print_specific_limits (cmd, mode); - continue; + 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; - current_limit = shell_ulimit (cmd, real_limit, 0, mode); + if (all_limits) + { + print_all_limits (mode == 0 ? LIMIT_SOFT : mode); + return (EXECUTION_SUCCESS); + } - if (setting) - { -#if !defined (HAVE_RESOURCE) - /* Most USG systems do not most allow limits to be raised by any - user other than root. There are, however, exceptions. */ - if (canraise (cmd, current_limit, real_limit) == 0) - { - builtin_error ("cannot raise limit: %s", strerror (EPERM)); - return (EXECUTION_FAILURE); - } -#endif /* !HAVE_RESOURCE */ - - if (shell_ulimit (cmd, real_limit, 1, mode) == (RLIMTYPE)-1) - { - builtin_error ("cannot raise limit: %s", strerror (errno)); - return (EXECUTION_FAILURE); - } - - continue; - } - else + /* 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) { - if (current_limit < 0) - builtin_error ("cannot get limit: %s", strerror (errno)); - else if (current_limit != RLIM_INFINITY) - print_rlimtype ((current_limit / block_factor), 1); - else - printf ("unlimited\n"); + builtin_error ("bad command: `%c'", cmdlist[c].cmd); + return (EX_USAGE); } } - while (list); + + 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); } -/* The ulimit that we call from within Bash. +static int +ulimit_internal (cmd, cmdarg, mode, multiple) + int cmd; + char *cmdarg; + int mode, multiple; +{ + int opt, limind, setting; + long block_factor; + RLIMTYPE current_limit, real_limit, limit; - WHICH says which limit to twiddle; SETTING is non-zero if NEWLIM - contains the desired new limit. Otherwise, the existing limit is - returned. If mode & LIMIT_HARD, the hard limit is used; if - mode & LIMIT_SOFT, the soft limit. Both may be set by specifying - -H and -S; if both are specified, or if neither is specified, the - soft limit will be returned. + limit = RLIM_INVALID; + setting = cmdarg != 0; + limind = _findlim (cmd); + if (mode == 0) + mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT; + opt = get_limit (limind, mode, ¤t_limit); + if (opt < 0) + { + builtin_error ("cannot get limit: %s", strerror (errno)); + return (EXECUTION_FAILURE); + } - Systems without BSD resource limits can specify only u_FILE_SIZE. - This includes most USG systems. + if (setting == 0) /* print the value of the specified limit */ + { + printone (limind, current_limit, multiple); + return (EXECUTION_SUCCESS); + } + + /* Setting the limit. */ + if (STREQ (cmdarg, "unlimited")) + limit = RLIM_INFINITY; + else if (all_digits (cmdarg)) + limit = string_to_rlimtype (cmdarg); + else + { + builtin_error ("bad non-numeric arg `%s'", cmdarg); + return (EXECUTION_FAILURE); + } - Chet Ramey supplied the BSD resource limit code. */ -static RLIMTYPE -shell_ulimit (which, newlim, setting, mode) - int which, setting, mode; - RLIMTYPE newlim; + block_factor = (limit == RLIM_INFINITY) ? 1 : limits[limind].block_factor; + real_limit = limit * block_factor; + + if (set_limit (limind, real_limit, mode) < 0) + { + builtin_error ("cannot modify limit: %s", strerror (errno)); + return (EXECUTION_FAILURE); + } + return (EXECUTION_SUCCESS); +} + +static int +get_limit (ind, mode, limptr) + int ind, mode; + RLIMTYPE *limptr; { + RLIMTYPE value; #if defined (HAVE_RESOURCE) struct rlimit limit; - int cmd; - - if (mode == 0) - mode |= LIMIT_SOFT; #endif - switch (which) + if (limits[ind].parameter >= 256) { -#if !defined (HAVE_RESOURCE) - - case u_FILE_SIZE: - if (!setting) + switch (limits[ind].parameter) { - /* ulimit () returns a number that is in 512 byte blocks, thus we - must multiply it by 512 to get back to bytes. This is false - only under HP/UX 6.x. */ - RLIMTYPE result; - - result = ulimit (1, 0L); - -# if defined (hpux) && !defined (_POSIX_VERSION) - return (result); -# else - return (result * 512); -# endif /* hpux 6.x */ + case RLIMIT_FILESIZE: + value = filesize (); + break; + case RLIMIT_PIPESIZE: + value = pipesize (); + break; + case RLIMIT_OPENFILES: + value = (RLIMTYPE)getdtablesize (); + break; + case RLIMIT_VIRTMEM: + value = getmaxvm (mode); + break; + case RLIMIT_MAXUPROC: + value = getmaxuprc (mode); + break; + default: + errno = EINVAL; + return -1; } - else - return (ulimit (2, newlim / 512L)); - - break; - -#else /* defined (HAVE_RESOURCE) */ - - case u_FILE_SIZE: - cmd = RLIMIT_FSIZE; - goto do_ulimit; - - case u_CORE_FILE_SIZE: - cmd = RLIMIT_CORE; - goto do_ulimit; - - case u_DATA_SEG_SIZE: - cmd = RLIMIT_DATA; - goto do_ulimit; - -#if !defined (USGr4) - case u_PHYS_MEM_SIZE: -# if defined (RLIMIT_RSS) - cmd = RLIMIT_RSS; -# else /* !RLIMIT_RSS */ - errno = EINVAL; - return ((RLIMTYPE)-1); -# endif /* !RLIMIT_RSS */ - - goto do_ulimit; -#endif /* USGr4 */ - - case u_CPU_TIME_LIMIT: -#if defined (RLIMIT_CPU) - cmd = RLIMIT_CPU; - goto do_ulimit; + *limptr = value; + return ((value == RLIM_INVALID) ? -1 : 0); + } + else + { +#if defined (HAVE_RESOURCE) + if (getrlimit (limits[ind].parameter, &limit) < 0) + return -1; + value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max; + *limptr = value; + return 0; #else errno = EINVAL; - return ((RLIMTYPE)-1); -# endif /* !RLIMIT_CPU */ - - - case u_STACK_SIZE: - cmd = RLIMIT_STACK; - - do_ulimit: - - if (getrlimit (cmd, &limit) != 0) - return ((RLIMTYPE)-1); - - if (!setting) - { - if (mode & LIMIT_SOFT) - return (limit.rlim_cur); - else - return (limit.rlim_max); - } - else - { - if (mode & LIMIT_SOFT) - { - /* Non-root users are only allowed to raise a limit up to the - hard limit, not to infinity. */ - if (current_user.euid != 0 && newlim == RLIM_INFINITY) - limit.rlim_cur = limit.rlim_max; - else - limit.rlim_cur = newlim; - } - if (mode & LIMIT_HARD) - limit.rlim_max = newlim; - - return (setrlimit (cmd, &limit)); - } - - break; - -#endif /* HAVE_RESOURCE */ + return -1; +#endif + } +} - /* You can't get or set the pipe size with getrlimit, so we have to - cheat. */ - case u_PIPE_SIZE: - if (setting) - { - errno = EINVAL; - return ((RLIMTYPE)-1); - } - return (pipesize ()); +static int +set_limit (ind, newlim, mode) + int ind; + RLIMTYPE newlim; + int mode; +{ +#if defined (HAVE_RESOURCE) + struct rlimit limit; + RLIMTYPE val; +#endif - case u_NUM_OPEN_FILES: - if (setting) - { -#if defined (HAVE_RESOURCE) && defined (RLIMIT_NOFILE) - cmd = RLIMIT_NOFILE; - goto do_ulimit; -#else -# if defined (HAVE_SETDTABLESIZE) - return (setdtablesize (newlim)); -# else - errno = EINVAL; - return ((RLIMTYPE)-1); -# endif /* HAVE_SETDTABLESIZE */ -#endif /* !HAVE_RESOURCE || !RLIMIT_NOFILE */ - } - else - return (open_files (mode)); + if (limits[ind].parameter >= 256) + switch (limits[ind].parameter) + { + case RLIMIT_FILESIZE: +#if !defined (HAVE_RESOURCE) + return (ulimit (2, newlim / 512L)); +#endif - case u_MAX_VIRTUAL_MEM: - if (setting) - { - errno = EINVAL; - return ((RLIMTYPE)-1); - } - else - { + case RLIMIT_OPENFILES: +#if defined (HAVE_SETDTABLESIZE) + return (setdtablesize (newlim)); +#endif + case RLIMIT_PIPESIZE: + case RLIMIT_VIRTMEM: + case RLIMIT_MAXUPROC: + default: + errno = EINVAL; + return -1; + } + else + { #if defined (HAVE_RESOURCE) - return (getmaxvm (mode)); -#else /* !HAVE_RESOURCE */ - errno = EINVAL; - return ((RLIMTYPE)-1); -#endif /* !HAVE_RESOURCE */ - } - - case u_MAX_USER_PROCS: -#if defined (HAVE_RESOURCE) && defined (RLIMIT_NPROC) - cmd = RLIMIT_NPROC; - goto do_ulimit; -#else /* !HAVE_RESOURCE || !RLIMIT_NPROC */ - errno = EINVAL; - return ((RLIMTYPE)-1); -#endif /* !HAVE_RESOURCE || !RLIMIT_NPROC */ - - default: + if (getrlimit (limits[ind].parameter, &limit) < 0) + return -1; + val = (current_user.euid != 0 && newlim == RLIM_INFINITY) + ? 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 ((RLIMTYPE)-1); + return -1; +#endif } } -#if defined (HAVE_RESOURCE) static RLIMTYPE getmaxvm (mode) int mode; { +#if defined (HAVE_RESOURCE) struct rlimit rl; - -#if defined (RLIMIT_VMEM) - if (getrlimit (RLIMIT_VMEM, &rl) < 0) - return ((RLIMTYPE)-1); - else - return (((mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max) / 1024L); -#else /* !RLIMIT_VMEM */ RLIMTYPE maxdata, maxstack; if (getrlimit (RLIMIT_DATA, &rl) < 0) - return ((RLIMTYPE)-1); + return (RLIM_INVALID); else maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max; if (getrlimit (RLIMIT_STACK, &rl) < 0) - return ((RLIMTYPE)-1); + return (RLIM_INVALID); else maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max; /* Protect against overflow. */ return ((maxdata / 1024L) + (maxstack / 1024L)); -#endif /* !RLIMIT_VMEM */ -} +#else + errno = EINVAL; + return RLIM_INVALID; #endif /* HAVE_RESOURCE */ +} static RLIMTYPE -open_files (mode) - int mode; +filesize() { -#if !defined (RLIMIT_NOFILE) - return ((RLIMTYPE)getdtablesize ()); +#if !defined (HAVE_RESOURCE) + return ((RLIMTYPE)ulimit (1, 0L)); #else - struct rlimit rl; - - getrlimit (RLIMIT_NOFILE, &rl); - if (mode & LIMIT_SOFT) - return (rl.rlim_cur); - else - return (rl.rlim_max); + errno = EINVAL; + return RLIM_INVALID; #endif } @@ -607,125 +526,57 @@ pipesize () return ((RLIMTYPE) PIPESIZE); # else errno = EINVAL; - return ((RLIMTYPE)-1); + return RLIM_INVALID; # endif /* PIPESIZE */ #endif /* PIPE_BUF */ } -/* ulimit(2) returns information about file size limits in terms of 512-byte - blocks. This is the factor by which to divide to turn it into information - in terms of 1024-byte blocks. Except for hpux 6.x, which returns it in - terms of bytes. */ -#if !defined (hpux) || defined (_POSIX_VERSION) -# define ULIMIT_DIVISOR 2 -#else -# define ULIMIT_DIVISOR 1024 -#endif - -#if defined (HAVE_RESOURCE) - -typedef struct { - int option_cmd; /* The ulimit command for this limit. */ - int parameter; /* Parameter to pass to getrlimit (). */ - int block_factor; /* Blocking factor for specific limit. */ - char *description; /* Descriptive string to output. */ -} BSD_RESOURCE_LIMITS; - -static BSD_RESOURCE_LIMITS limits[] = { - { u_CORE_FILE_SIZE, RLIMIT_CORE, 1024, "core file size (blocks)" }, - { u_DATA_SEG_SIZE, RLIMIT_DATA, 1024, "data seg size (kbytes)" }, - { u_FILE_SIZE, RLIMIT_FSIZE, 1024, "file size (blocks)" }, -#if !defined (USGr4) && defined (RLIMIT_RSS) - { u_PHYS_MEM_SIZE, RLIMIT_RSS, 1024, "max memory size (kbytes)" }, -#endif /* USGr4 && RLIMIT_RSS */ - { u_STACK_SIZE, RLIMIT_STACK, 1024, "stack size (kbytes)" }, -#if defined (RLIMIT_CPU) - { u_CPU_TIME_LIMIT, RLIMIT_CPU, 1, "cpu time (seconds)" }, -#endif /* RLIMIT_CPU */ -#if defined (RLIMIT_NPROC) - { u_MAX_USER_PROCS, RLIMIT_NPROC, 1, "max user processes" }, -#endif /* RLIMIT_NPROC */ - { 0, 0, 0, (char *)NULL } -}; - -static void -print_bsd_limit (i, mode) - int i, mode; +static RLIMTYPE +getmaxuprc (mode) + int mode; { - struct rlimit rl; - RLIMTYPE limit; - - getrlimit (limits[i].parameter, &rl); - if (mode & LIMIT_HARD) - limit = rl.rlim_max; - else - limit = rl.rlim_cur; - printf ("%-25s", limits[i].description); - if (limit == RLIM_INFINITY) - printf ("unlimited\n"); - else - print_rlimtype ((limit / limits[i].block_factor), 1); +# if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) + return ((RLIMTYPE)sysconf (_SC_CHILD_MAX)); +# else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ +# if defined (MAXUPRC) + return ((RLIMTYPE)MAXUPRC); +# else /* MAXUPRC */ + errno = EINVAL; + return RLIM_INVALID; +# endif /* !MAXUPRC */ +# endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ } static void -print_specific_bsd_limits (cmd, mode) - int cmd, mode; +print_all_limits (mode) + int mode; { register int i; + RLIMTYPE value; - for (i = 0; limits[i].option_cmd; i++) - if (cmd & limits[i].option_cmd) - print_bsd_limit (i, mode); -} -#endif /* HAVE_RESOURCE */ - -/* Print the limits corresponding to a specific set of resources. This is - called when an option string contains more than one character (e.g. -at), - because limits may not be specified with that kind of argument. */ -static void -print_specific_limits (cmd, mode) - int cmd, mode; -{ if (mode == 0) - mode = LIMIT_SOFT; - -#if defined (HAVE_RESOURCE) - print_specific_bsd_limits (cmd, mode); -#else /* !HAVE_RESOURCE */ - if (cmd & u_FILE_SIZE) - { - printf ("%-25s", "file size (blocks)"); - print_rlimtype ((ulimit (1, 0L) / ULIMIT_DIVISOR), 1); - } -#endif /* !HAVE_RESOURCE */ - - if (cmd & u_PIPE_SIZE) - { - printf ("%-25s", "pipe size (512 bytes)"); - print_rlimtype ((pipesize () / 512), 1); - } - - if (cmd & u_NUM_OPEN_FILES) - { - printf ("%-25s", "open files"); - print_rlimtype (open_files (mode), 1); - } + mode |= LIMIT_SOFT; -#if defined (HAVE_RESOURCE) - if (cmd & u_MAX_VIRTUAL_MEM) + for (i = 0; limits[i].option > 0; i++) { - printf ("%-25s", "virtual memory (kbytes)"); - print_rlimtype (getmaxvm (mode), 1); + if (get_limit (i, mode, &value) < 0) + value = RLIM_INVALID; + printone (i, value, 1); } -#endif /* HAVE_RESOURCE */ } static void -print_all_limits (mode) - int mode; +printone (limind, curlim, pdesc) + int limind; + RLIMTYPE curlim; + int pdesc; { - if (mode == 0) - mode |= LIMIT_SOFT; - - print_specific_limits (u_ALL_LIMITS, mode); + if (pdesc) + printf (DESCFMT, limits[limind].description); + if (curlim == RLIM_INFINITY) + puts ("unlimited"); + else if (curlim == RLIM_INVALID) + printf ("cannot get limit: %s\n", strerror (errno)); + else + print_rlimtype ((curlim / limits[limind].block_factor), 1); }