rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit bf61b6f19e8292742ed3dedcf58457ff3607173a
parent c09b7f1b7658ff06291ec6f9360db73b67a6ed82
Author: tjg <tjg>
Date:   Fri, 23 Nov 2001 16:03:22 +0000

  Bug: parselimit() was broken in various ways (thanks Chris
  Siebenmann).

Diffstat:
Mbuiltins.c | 79++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mrlimit.h | 11+++++++++++
2 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/builtins.c b/builtins.c @@ -423,14 +423,7 @@ static void b_newpgrp(char **av) { /* Berkeley limit support was cleaned up by Paul Haahr. */ #if HAVE_SETRLIMIT -typedef struct Suffix Suffix; -struct Suffix { - const Suffix *next; - long amount; - char *name; -}; - -static const Suffix +static const struct Suffix kbsuf = { NULL, 1024, "k" }, mbsuf = { &kbsuf, 1024*1024, "m" }, gbsuf = { &mbsuf, 1024*1024*1024, "g" }, @@ -439,32 +432,39 @@ static const Suffix htsuf = { &mtsuf, 60*60, "h" }; #define SIZESUF &gbsuf #define TIMESUF &htsuf -#define NOSUF ((Suffix *) NULL) /* for RLIMIT_NOFILE on SunOS 4.1 */ +#define NOSUF ((struct Suffix *) NULL) /* for RLIMIT_NOFILE on SunOS 4.1 */ -typedef struct { - char *name; - int flag; - const Suffix *suffix; -} Limit; -static const Limit limits[] = { +static const struct Limit limits[] = { { "cputime", RLIMIT_CPU, TIMESUF }, { "filesize", RLIMIT_FSIZE, SIZESUF }, { "datasize", RLIMIT_DATA, SIZESUF }, { "stacksize", RLIMIT_STACK, SIZESUF }, { "coredumpsize", RLIMIT_CORE, SIZESUF }, -#ifdef RLIMIT_RSS /* SysVr4 does not have this */ - { "memoryuse", RLIMIT_RSS, SIZESUF }, +#ifdef RLIMIT_NOFILE /* SUSv2, but not universal */ + { "descriptors", RLIMIT_NOFILE, NOSUF }, #endif -#ifdef RLIMIT_VMEM /* instead, they have this! */ - { "vmemory", RLIMIT_VMEM, SIZESUF }, +#ifdef RLIMIT_AS /* SUSv2, but not universal */ + { "memoryuse", RLIMIT_AS, SIZESUF }, #endif -#ifdef RLIMIT_NOFILE /* SunOS 4.1 adds a limit on file descriptors */ - { "descriptors", RLIMIT_NOFILE, NOSUF }, +#if defined(RLIMIT_VMEM) && !defined(RLIMIT_AS) /* old name for AS */ + { "memoryuse", RLIMIT_VMEM, SIZESUF }, +#endif +#ifdef RLIMIT_RSS + { "memoryrss", RLIMIT_RSS, SIZESUF }, +#endif +#ifdef RLIMIT_NPROC + { "maxproc", RLIMIT_NPROC, NOSUF }, +#endif +#ifdef RLIMIT_MEMLOCK + { "memorylocked", RLIMIT_MEMLOCK, SIZESUF }, +#endif +#ifdef RLIMIT_LOCKS + { "filelocks", RLIMIT_LOCKS, NOSUF }, #endif { NULL, 0, NULL } }; -static void printlimit(const Limit *limit, bool hard) { +static void printlimit(const struct Limit *limit, bool hard) { struct rlimit rlim; rlim_t lim; getrlimit(limit->flag, &rlim); @@ -475,7 +475,7 @@ static void printlimit(const Limit *limit, bool hard) { if (lim == RLIM_INFINITY) fprint(1, "%s \tunlimited\n", limit->name); else { - const Suffix *suf; + const struct Suffix *suf; for (suf = limit->suffix; suf != NULL; suf = suf->next) if (lim % suf->amount == 0 && (lim != 0 || suf->amount > 1)) { lim /= suf->amount; @@ -485,30 +485,39 @@ static void printlimit(const Limit *limit, bool hard) { } } -static rlim_t parselimit(const Limit *limit, char *s) { +static rlim_t parselimit(const struct Limit *resource, rlim_t *limit, char *s) { char *t; int len = strlen(s); - long lim = 1; - const Suffix *suf = limit->suffix; - if (streq(s, "unlimited")) - return RLIM_INFINITY; + const struct Suffix *suf = resource->suffix; + + *limit = 1; + if (streq(s, "unlimited")) { + *limit = RLIM_INFINITY; + return TRUE; + } if (suf == TIMESUF && (t = strchr(s, ':')) != NULL) { + int min, sec; *t++ = '\0'; - lim = 60 * a2u(s) + a2u(t); + min = a2u(s); sec = a2u(t); + if (min == -1 || sec == -1) return FALSE; + *limit = 60 * min + sec; } else { + int n; for (; suf != NULL; suf = suf->next) if (streq(suf->name, s + len - strlen(suf->name))) { s[len - strlen(suf->name)] = '\0'; - lim *= suf->amount; + *limit *= suf->amount; break; } - lim *= a2u(s); + n = a2u(s); + if (n == -1) return FALSE; + *limit *= n; } - return lim; + return TRUE; } static void b_limit(char **av) { - const Limit *lp = limits; + const struct Limit *lp = limits; bool hard = FALSE; if (*++av != NULL && streq(*av, "-h")) { av++; @@ -532,9 +541,9 @@ static void b_limit(char **av) { printlimit(lp, hard); else { struct rlimit rlim; - long pl; + rlim_t pl; getrlimit(lp->flag, &rlim); - if ((pl = parselimit(lp, *av)) < 0) { + if (!parselimit(lp, &pl, *av)) { fprint(2, "bad limit\n"); set(FALSE); return; diff --git a/rlimit.h b/rlimit.h @@ -39,4 +39,15 @@ typedef long rlim_t; #define RLIMIT_NOFILE RLIMIT_OFILE #endif +struct Suffix { + const struct Suffix *next; + long amount; + char *name; +}; + +struct Limit { + char *name; + int flag; + const struct Suffix *suffix; +}; #endif /* HAVE_SETRLIMIT */