hush: fix set [--] params. Closes bug 199.
function old new delta builtin_set 55 194 +139 add_strings_to_strings - 130 +130 add_string_to_strings 110 26 -84 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 269/-84) Total: 185 bytes
This commit is contained in:
parent
1bb3d7e450
commit
11fb7cf5af
70
shell/hush.c
70
shell/hush.c
@ -471,8 +471,9 @@ struct globals {
|
|||||||
smallint fake_mode;
|
smallint fake_mode;
|
||||||
/* these three support $?, $#, and $1 */
|
/* these three support $?, $#, and $1 */
|
||||||
smalluint last_return_code;
|
smalluint last_return_code;
|
||||||
|
smalluint global_args_malloced;
|
||||||
|
int global_argc; /* NB: $# + 1 */
|
||||||
char **global_argv;
|
char **global_argv;
|
||||||
int global_argc;
|
|
||||||
#if ENABLE_HUSH_LOOPS
|
#if ENABLE_HUSH_LOOPS
|
||||||
unsigned depth_break_continue;
|
unsigned depth_break_continue;
|
||||||
unsigned depth_of_loop;
|
unsigned depth_of_loop;
|
||||||
@ -646,7 +647,7 @@ static char *unbackslash(char *src)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **add_strings_to_strings(char **strings, char **add)
|
static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned count1;
|
unsigned count1;
|
||||||
@ -671,7 +672,7 @@ static char **add_strings_to_strings(char **strings, char **add)
|
|||||||
v[count1 + count2] = NULL;
|
v[count1 + count2] = NULL;
|
||||||
i = count2;
|
i = count2;
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
v[count1 + i] = add[i];
|
v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,7 +681,7 @@ static char **add_string_to_strings(char **strings, char *add)
|
|||||||
char *v[2];
|
char *v[2];
|
||||||
v[0] = add;
|
v[0] = add;
|
||||||
v[1] = NULL;
|
v[1] = NULL;
|
||||||
return add_strings_to_strings(strings, v);
|
return add_strings_to_strings(strings, v, /*dup:*/ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void putenv_all(char **strings)
|
static void putenv_all(char **strings)
|
||||||
@ -4644,17 +4645,68 @@ static int builtin_read(char **argv)
|
|||||||
return set_local_var(string, 0);
|
return set_local_var(string, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* built-in 'set [VAR=value]' handler */
|
/* built-in 'set' handler
|
||||||
|
* SUSv3 says:
|
||||||
|
* set [-abCefmnuvx] [-h] [-o option] [argument...]
|
||||||
|
* set [+abCefmnuvx] [+h] [+o option] [argument...]
|
||||||
|
* set -- [argument...]
|
||||||
|
* set -o
|
||||||
|
* set +o
|
||||||
|
* Implementations shall support the options in both their hyphen and
|
||||||
|
* plus-sign forms. These options can also be specified as options to sh.
|
||||||
|
* Examples:
|
||||||
|
* Write out all variables and their values: set
|
||||||
|
* Set $1, $2, and $3 and set "$#" to 3: set c a b
|
||||||
|
* Turn on the -x and -v options: set -xv
|
||||||
|
* Unset all positional parameters: set --
|
||||||
|
* Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
|
||||||
|
* Set the positional parameters to the expansion of x, even if x expands
|
||||||
|
* with a leading '-' or '+': set -- $x
|
||||||
|
*
|
||||||
|
* So far, we only support "set -- [argument...]" by ignoring all options
|
||||||
|
* (also, "-o option" will be mishandled by taking "option" as parameter #1).
|
||||||
|
*/
|
||||||
static int builtin_set(char **argv)
|
static int builtin_set(char **argv)
|
||||||
{
|
{
|
||||||
char *temp = argv[1];
|
|
||||||
struct variable *e;
|
struct variable *e;
|
||||||
|
char **pp;
|
||||||
|
char *arg = *++argv;
|
||||||
|
|
||||||
if (temp == NULL)
|
if (arg == NULL) {
|
||||||
for (e = G.top_var; e; e = e->next)
|
for (e = G.top_var; e; e = e->next)
|
||||||
puts(e->varstr);
|
puts(e->varstr);
|
||||||
else
|
} else {
|
||||||
set_local_var(xstrdup(temp), 0);
|
/* NB: G.global_argv[0] ($0) is never freed/changed */
|
||||||
|
|
||||||
|
if (G.global_args_malloced) {
|
||||||
|
pp = G.global_argv;
|
||||||
|
while (*++pp)
|
||||||
|
free(*pp);
|
||||||
|
G.global_argv[1] = NULL;
|
||||||
|
} else {
|
||||||
|
G.global_args_malloced = 1;
|
||||||
|
pp = xzalloc(sizeof(pp[0]) * 2);
|
||||||
|
pp[0] = G.global_argv[0]; /* retain $0 */
|
||||||
|
G.global_argv = pp;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (arg[0] == '+')
|
||||||
|
continue;
|
||||||
|
if (arg[0] != '-')
|
||||||
|
break;
|
||||||
|
if (arg[1] == '-' && arg[2] == '\0') {
|
||||||
|
argv++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((arg = *++argv) != NULL);
|
||||||
|
/* Now argv[0] is 1st argument */
|
||||||
|
|
||||||
|
/* This realloc's G.global_argv */
|
||||||
|
G.global_argv = pp = add_strings_to_strings(G.global_argv, argv, /*dup:*/ 1);
|
||||||
|
G.global_argc = 1;
|
||||||
|
while (*++pp)
|
||||||
|
G.global_argc++;
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user