aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c36
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);