diff options
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/shell/ash.c b/shell/ash.c index f16d7fb6a..1aead6df4 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -314,9 +314,12 @@ typedef long arith_t; /* ============ Shell options */ +/* If you add/change options hare, update --help text too */ static const char *const optletters_optnames[] = { "e" "errexit", "f" "noglob", +/* bash has '-o ignoreeof', but no short synonym -I for it */ +/* (in bash, set -I disables invisible variables (what's that?)) */ "I" "ignoreeof", /* The below allowed this invocation: * ash -c 'set -i; echo $-; sleep 5; echo $-' @@ -325,9 +328,10 @@ static const char *const optletters_optnames[] = { * In our code, this is denoted by empty long name: */ "i" "", +/* (removing "i" altogether would remove it from "$-", not good) */ "m" "monitor", "n" "noexec", -/* Ditto: bash has no "set -s" */ +/* Ditto: bash has no "set -s", "set -c" */ "s" "", "c" "", "x" "xtrace", @@ -7011,7 +7015,8 @@ subevalvar(char *start, char *str, int strloc, slash_pos = -1; if (repl) { slash_pos = expdest - ((char *)stackblock() + strloc); - STPUTC('/', expdest); + if (!(flag & EXP_DISCARD)) + STPUTC('/', expdest); //bb_error_msg("repl+1:'%s'", repl + 1); p = argstr(repl + 1, (flag & EXP_DISCARD) | EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */ *repl = '/'; @@ -7173,7 +7178,7 @@ subevalvar(char *start, char *str, int strloc, len = 0; idx = startp; end = str - 1; - while (idx < end) { + while (idx <= end) { try_to_match: loc = scanright(idx, rmesc, rmescend, str, quotes, 1); //bb_error_msg("scanright('%s'):'%s'", str, loc); @@ -7181,6 +7186,8 @@ subevalvar(char *start, char *str, int strloc, /* No match, advance */ char *restart_detect = stackblock(); skip_matching: + if (idx >= end) + break; STPUTC(*idx, expdest); if (quotes && (unsigned char)*idx == CTLESC) { idx++; @@ -7193,8 +7200,6 @@ subevalvar(char *start, char *str, int strloc, len++; rmesc++; /* continue; - prone to quadratic behavior, smarter code: */ - if (idx >= end) - break; if (str[0] == '*') { /* Pattern is "*foo". If "*foo" does not match "long_string", * it would never match "ong_string" etc, no point in trying. @@ -11371,10 +11376,10 @@ static void FAST_FUNC change_epoch(struct var *vepoch, const char *fmt) { struct timeval tv; - char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3]; + char buffer[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; - gettimeofday(&tv, NULL); - sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec); + xgettimeofday(&tv); + sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); setvar(vepoch->var_text, buffer, VNOFUNC); vepoch->flags &= ~VNOFUNC; } @@ -11382,13 +11387,13 @@ change_epoch(struct var *vepoch, const char *fmt) static void FAST_FUNC change_seconds(const char *value UNUSED_PARAM) { - change_epoch(&vepochs, "%lu"); + change_epoch(&vepochs, "%llu"); } static void FAST_FUNC change_realtime(const char *value UNUSED_PARAM) { - change_epoch(&vepochr, "%lu.%06u"); + change_epoch(&vepochr, "%llu.%06u"); } #endif @@ -14265,7 +14270,8 @@ init(void) //usage:#define ash_trivial_usage -//usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//usage: "[-il] [-/+Cabefmnuvx] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" +//////// comes from ^^^^^^^^^^optletters //usage:#define ash_full_usage "\n\n" //usage: "Unix shell interpreter" @@ -14312,9 +14318,9 @@ procargs(char **argv) } if (mflag == 2) mflag = iflag; + /* Unset options which weren't explicitly set or unset */ for (i = 0; i < NOPTS; i++) - if (optlist[i] == 2) - optlist[i] = 0; + optlist[i] &= 1; /* same effect as "if (optlist[i] == 2) optlist[i] = 0;" */ #if DEBUG == 2 debug = 1; #endif @@ -14499,7 +14505,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) if (sflag || minusc == NULL) { #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY - if (iflag) { + if (line_input_state) { const char *hp = lookupvar("HISTFILE"); if (!hp) { hp = lookupvar("HOME"); @@ -14513,7 +14519,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) } } if (hp) - line_input_state->hist_file = hp; + line_input_state->hist_file = xstrdup(hp); # if ENABLE_FEATURE_SH_HISTFILESIZE hp = lookupvar("HISTFILESIZE"); line_input_state->max_history = size_from_HISTFILESIZE(hp); |