From 7dd741a4015976470bd5b8beb3e20e6343bd636c Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 20 Apr 2008 21:30:29 +0000 Subject: [PATCH] =?UTF-8?q?=E2=80=A2=20revert=20the=20oksh=20code=20to=20b?= =?UTF-8?q?e=20able=20to=20set=20multiple=20ulimits=20in=20one=20=20=20inv?= =?UTF-8?q?ocation,=20until=20it=20works=20with=20a=20common=20idiom:=20?= =?UTF-8?q?=E2=80=9Culimit=20-dS=20262144=E2=80=9D=20=20=20(but=20keep=20s?= =?UTF-8?q?ome=20goodies)=20=E2=80=A2=20add=20a=20regression=20test=20for?= =?UTF-8?q?=20that?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check.t | 15 ++++- funcs.c | 178 ++++++++++++++++++++++---------------------------------- mksh.1 | 9 ++- 3 files changed, 89 insertions(+), 113 deletions(-) diff --git a/check.t b/check.t index 92ef550..d02ee38 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.186 2008/04/20 01:23:49 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.187 2008/04/20 21:30:28 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -4977,3 +4977,16 @@ expected-stdout: 000001A0 BF 0A FF 0A C2 0A EF BF - C0 0A C0 80 0A E0 80 80 |.�.�.���.��.���| 000001B0 0A EF BF BD EF BF BE EF - BF BF 0A |.�������.| --- +name: ulimit-1 +description: + Check if we can use a specific syntax idiom for ulimit +stdin: + if ! x=$(ulimit -d); then + print expected to fail on this OS + else + ulimit -dS $x && print okay + fi +expected-stdout: + okay +--- + diff --git a/funcs.c b/funcs.c index fcf04a1..10a550b 100644 --- a/funcs.c +++ b/funcs.c @@ -5,7 +5,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.77 2008/04/19 22:15:03 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.78 2008/04/20 21:30:29 tg Exp $"); /* A leading = means assignments before command are kept; * a leading * means a POSIX special builtin; @@ -2860,9 +2860,6 @@ struct limits { char option; }; -static void print_ulimit(const struct limits *, int); -static int set_ulimit(const struct limits *, const char *, int); - int c_ulimit(const char **wp) { @@ -2909,23 +2906,23 @@ c_ulimit(const char **wp) #endif { NULL, 0, 0, 0 } }; - static char opts[4 + NELEM(limits) * 2]; - int how = SOFT | HARD, optc; - bool all = false; + static char opts[3 + NELEM(limits)]; + rlim_t val = (rlim_t)0; + int how = SOFT | HARD, optc, what; + bool all = false, set; const struct limits *l; + struct rlimit limit; if (!opts[0]) { /* build options string on first call - yuck */ char *p = opts; *p++ = 'H'; *p++ = 'S'; *p++ = 'a'; - for (l = limits; l->name; l++) { + for (l = limits; l->name; l++) *p++ = l->option; - *p++ = '#'; - } *p = '\0'; } - /* first check for -a, -H and -S */ + what = 'f'; while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) switch (optc) { case 'H': @@ -2940,96 +2937,85 @@ c_ulimit(const char **wp) case '?': return (1); default: - break; + what = optc; } - if (wp[builtin_opt.optind] != NULL) { - bi_errorf("usage: ulimit [-acdfHLlmnpSsTtvw] [value]"); + for (l = limits; l->name && l->option != what; l++) + ; + if (!l->name) { + internal_warningf("ulimit: %c", what); return (1); } - /* then parse and act on the actual limits, one at a time */ - ksh_getopt_reset(&builtin_opt, GF_ERROR); - while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) - switch (optc) { - case 'a': - case 'H': - case 'S': - break; - case '?': - return (1); - default: - for (l = limits; l->name && l->option != optc; l++) - ; - if (!l->name) { - internal_warningf("ulimit: %c", optc); - return (1); - } - if (!builtin_opt.optarg) - print_ulimit(l, how); - else if (set_ulimit(l, builtin_opt.optarg, how)) - return (1); - break; - } - wp += builtin_opt.optind; + if ((set = *wp ? true : false)) { + if (all || wp[1]) { + bi_errorf("too many arguments"); + return (1); + } + if (strcmp(wp[0], "unlimited") == 0) + val = (rlim_t)RLIM_INFINITY; + else { + long rval; - if (all) + if (!evaluate(wp[0], &rval, KSH_RETURN_ERROR, false)) + return (1); + /* Avoid problems caused by typos that + * evaluate misses due to evaluating unset + * parameters to 0... + * If this causes problems, will have to + * add parameter to evaluate() to control + * if unset params are 0 or an error. + */ + if (!rval && !ksh_isdigit(wp[0][0])) { + bi_errorf("invalid limit: %s", wp[0]); + return (1); + } + val = (rlim_t)((rlim_t)rval * l->factor); + } + } + if (all) { for (l = limits; l->name; l++) { shprintf("%-20s ", l->name); - print_ulimit(l, how); + if (getrlimit(l->resource, &limit)) { + shf_puts("unknown\n", shl_stdout); + continue; + } + if (how & SOFT) + val = limit.rlim_cur; + else if (how & HARD) + val = limit.rlim_max; + if (val == (rlim_t)RLIM_INFINITY) + shf_puts("unlimited\n", shl_stdout); + else { + val = (rlim_t)(val / l->factor); + shprintf("%ld\n", (long)val); + } } - else if (builtin_opt.optind == 1) { - /* no limit specified, use file size as default */ -#ifndef RLIMIT_FSIZE - internal_warningf("ulimit: need argument"); - return (1); -#else -#ifdef RLIMIT_CPU - l = &limits[1]; -#else - l = &limits[0]; -#endif - if (!wp[0]) - print_ulimit(l, how); - else if (set_ulimit(l, wp[0], how)) - return(1); -#endif + return 0; } - return (0); -} - -static int -set_ulimit(const struct limits *l, const char *v, int how) -{ - rlim_t val = (rlim_t)0; - struct rlimit limit; - - if (strcmp(v, "unlimited") == 0) - val = (rlim_t)RLIM_INFINITY; - else { - long rval; - - if (!evaluate(v, &rval, KSH_RETURN_ERROR, false)) - return (1); - /* - * Avoid problems caused by typos that evaluate misses due - * to evaluating unset parameters to 0... - * If this causes problems, will have to add parameter to - * evaluate() to control if unset params are 0 or an error. - */ - if (!rval && !ksh_isdigit(v[0])) { - bi_errorf("invalid limit: %s", v); - return (1); - } - val = (rlim_t)rval * l->factor; - } - if (getrlimit(l->resource, &limit) < 0) { /* some cannot be read, e.g. Linux RLIMIT_LOCKS */ + if (!set) { + shf_puts("unknown\n", shl_stdout); + return (0); + } limit.rlim_cur = RLIM_INFINITY; limit.rlim_max = RLIM_INFINITY; } + if (!set) { + if (how & SOFT) + val = limit.rlim_cur; + else if (how & HARD) + val = limit.rlim_max; + if (val == (rlim_t)RLIM_INFINITY) + shf_puts("unlimited\n", shl_stdout); + else { + val = (rlim_t)(val / l->factor); + shprintf("%ld\n", (long)val); + } + return (0); + } if (how & SOFT) limit.rlim_cur = val; if (how & HARD) @@ -3044,28 +3030,6 @@ set_ulimit(const struct limits *l, const char *v, int how) return (0); } -static void -print_ulimit(const struct limits *l, int how) -{ - rlim_t val = (rlim_t)0; - struct rlimit limit; - - if (getrlimit(l->resource, &limit)) { - shf_puts("unknown\n", shl_stdout); - return; - } - if (how & SOFT) - val = limit.rlim_cur; - else if (how & HARD) - val = limit.rlim_max; - if (val == RLIM_INFINITY) - shf_puts("unlimited\n", shl_stdout); - else { - val /= l->factor; - shprintf("%ld\n", (long)val); - } -} - int c_rename(const char **wp) { diff --git a/mksh.1 b/mksh.1 index 04098df..eb11c60 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.122 2008/04/20 01:47:59 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.123 2008/04/20 21:30:29 tg Exp $ .\" $OpenBSD: ksh.1,v 1.121 2008/03/21 12:51:19 millert Exp $ .\"- .\" Try to make GNU groff and AT&T nroff more compatible @@ -4092,16 +4092,15 @@ unless they are also given on the same command line. .Pp .It Xo .Ic ulimit -.Op Fl acdfHLlmnpSsTtvw Op Ar value -.Ar ... +.Op Fl acdfHLlmnpSsTtvw +.Op Ar value .Xc Display or set process limits. If no options are used, the file size limit .Pq Fl f is assumed. .Ar value , -if specified, may be either an arithmetic expression starting with a -number or the word +if specified, may be either an arithmetic expression or the word .Dq unlimited . The limits affect the shell and any processes created by the shell after a limit is imposed.