hush: support "cd -- DIR" and such
function old new delta skip_dash_dash - 33 +33 builtin_exit 43 48 +5 builtin_umask 121 125 +4 builtin_shift 115 119 +4 builtin_cd 71 75 +4 builtin_wait 271 274 +3 builtin_source 171 174 +3 builtin_exec 57 60 +3 builtin_eval 46 45 -1 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 7/1 up/down: 59/-1) Total: 58 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
40477e2fdb
commit
b131ccec9c
46
shell/hush.c
46
shell/hush.c
@ -7258,11 +7258,20 @@ static int FAST_FUNC builtin_printf(char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char **skip_dash_dash(char **argv)
|
||||||
|
{
|
||||||
|
argv++;
|
||||||
|
if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0')
|
||||||
|
argv++;
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
static int FAST_FUNC builtin_eval(char **argv)
|
static int FAST_FUNC builtin_eval(char **argv)
|
||||||
{
|
{
|
||||||
int rcode = EXIT_SUCCESS;
|
int rcode = EXIT_SUCCESS;
|
||||||
|
|
||||||
if (*++argv) {
|
argv = skip_dash_dash(argv);
|
||||||
|
if (*argv) {
|
||||||
char *str = expand_strvec_to_string(argv);
|
char *str = expand_strvec_to_string(argv);
|
||||||
/* bash:
|
/* bash:
|
||||||
* eval "echo Hi; done" ("done" is syntax error):
|
* eval "echo Hi; done" ("done" is syntax error):
|
||||||
@ -7277,7 +7286,10 @@ static int FAST_FUNC builtin_eval(char **argv)
|
|||||||
|
|
||||||
static int FAST_FUNC builtin_cd(char **argv)
|
static int FAST_FUNC builtin_cd(char **argv)
|
||||||
{
|
{
|
||||||
const char *newdir = argv[1];
|
const char *newdir;
|
||||||
|
|
||||||
|
argv = skip_dash_dash(argv);
|
||||||
|
newdir = argv[0];
|
||||||
if (newdir == NULL) {
|
if (newdir == NULL) {
|
||||||
/* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
|
/* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
|
||||||
* bash says "bash: cd: HOME not set" and does nothing
|
* bash says "bash: cd: HOME not set" and does nothing
|
||||||
@ -7301,7 +7313,8 @@ static int FAST_FUNC builtin_cd(char **argv)
|
|||||||
|
|
||||||
static int FAST_FUNC builtin_exec(char **argv)
|
static int FAST_FUNC builtin_exec(char **argv)
|
||||||
{
|
{
|
||||||
if (*++argv == NULL)
|
argv = skip_dash_dash(argv);
|
||||||
|
if (argv[0] == NULL)
|
||||||
return EXIT_SUCCESS; /* bash does this */
|
return EXIT_SUCCESS; /* bash does this */
|
||||||
|
|
||||||
/* Careful: we can end up here after [v]fork. Do not restore
|
/* Careful: we can end up here after [v]fork. Do not restore
|
||||||
@ -7334,12 +7347,13 @@ static int FAST_FUNC builtin_exit(char **argv)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* note: EXIT trap is run by hush_exit */
|
/* note: EXIT trap is run by hush_exit */
|
||||||
if (*++argv == NULL)
|
argv = skip_dash_dash(argv);
|
||||||
|
if (argv[0] == NULL)
|
||||||
hush_exit(G.last_exitcode);
|
hush_exit(G.last_exitcode);
|
||||||
/* mimic bash: exit 123abc == exit 255 + error msg */
|
/* mimic bash: exit 123abc == exit 255 + error msg */
|
||||||
xfunc_error_retval = 255;
|
xfunc_error_retval = 255;
|
||||||
/* bash: exit -2 == exit 254, no error msg */
|
/* bash: exit -2 == exit 254, no error msg */
|
||||||
hush_exit(xatoi(*argv) & 0xff);
|
hush_exit(xatoi(argv[0]) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_escaped(const char *s)
|
static void print_escaped(const char *s)
|
||||||
@ -7668,7 +7682,7 @@ static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
|
|||||||
"------------------\n");
|
"------------------\n");
|
||||||
for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
|
for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
|
||||||
if (x->b_descr)
|
if (x->b_descr)
|
||||||
printf("%s\t%s\n", x->b_cmd, x->b_descr);
|
printf("%-10s%s\n", x->b_cmd, x->b_descr);
|
||||||
}
|
}
|
||||||
bb_putchar('\n');
|
bb_putchar('\n');
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@ -7851,8 +7865,9 @@ static int FAST_FUNC builtin_set(char **argv)
|
|||||||
static int FAST_FUNC builtin_shift(char **argv)
|
static int FAST_FUNC builtin_shift(char **argv)
|
||||||
{
|
{
|
||||||
int n = 1;
|
int n = 1;
|
||||||
if (argv[1]) {
|
argv = skip_dash_dash(argv);
|
||||||
n = atoi(argv[1]);
|
if (argv[0]) {
|
||||||
|
n = atoi(argv[0]);
|
||||||
}
|
}
|
||||||
if (n >= 0 && n < G.global_argc) {
|
if (n >= 0 && n < G.global_argc) {
|
||||||
if (G.global_args_malloced) {
|
if (G.global_args_malloced) {
|
||||||
@ -7877,12 +7892,13 @@ static int FAST_FUNC builtin_source(char **argv)
|
|||||||
smallint sv_flg;
|
smallint sv_flg;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
arg_path = NULL;
|
argv = skip_dash_dash(argv);
|
||||||
filename = *++argv;
|
filename = argv[0];
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
/* bash says: "bash: .: filename argument required" */
|
/* bash says: "bash: .: filename argument required" */
|
||||||
return 2; /* bash compat */
|
return 2; /* bash compat */
|
||||||
}
|
}
|
||||||
|
arg_path = NULL;
|
||||||
if (!strchr(filename, '/')) {
|
if (!strchr(filename, '/')) {
|
||||||
arg_path = find_in_path(filename);
|
arg_path = find_in_path(filename);
|
||||||
if (arg_path)
|
if (arg_path)
|
||||||
@ -7920,11 +7936,12 @@ static int FAST_FUNC builtin_umask(char **argv)
|
|||||||
mode_t mask;
|
mode_t mask;
|
||||||
|
|
||||||
mask = umask(0);
|
mask = umask(0);
|
||||||
if (argv[1]) {
|
argv = skip_dash_dash(argv);
|
||||||
|
if (argv[0]) {
|
||||||
mode_t old_mask = mask;
|
mode_t old_mask = mask;
|
||||||
|
|
||||||
mask ^= 0777;
|
mask ^= 0777;
|
||||||
rc = bb_parse_mode(argv[1], &mask);
|
rc = bb_parse_mode(argv[0], &mask);
|
||||||
mask ^= 0777;
|
mask ^= 0777;
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
mask = old_mask;
|
mask = old_mask;
|
||||||
@ -7932,7 +7949,7 @@ static int FAST_FUNC builtin_umask(char **argv)
|
|||||||
* bash: umask: 'q': invalid symbolic mode operator
|
* bash: umask: 'q': invalid symbolic mode operator
|
||||||
* bash: umask: 999: octal number out of range
|
* bash: umask: 999: octal number out of range
|
||||||
*/
|
*/
|
||||||
bb_error_msg("%s: '%s' invalid mode", argv[0], argv[1]);
|
bb_error_msg("umask: '%s' invalid mode", argv[0]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
@ -7988,7 +8005,8 @@ static int FAST_FUNC builtin_wait(char **argv)
|
|||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
int status, sig;
|
int status, sig;
|
||||||
|
|
||||||
if (*++argv == NULL) {
|
argv = skip_dash_dash(argv);
|
||||||
|
if (argv[0] == NULL) {
|
||||||
/* Don't care about wait results */
|
/* Don't care about wait results */
|
||||||
/* Note 1: must wait until there are no more children */
|
/* Note 1: must wait until there are no more children */
|
||||||
/* Note 2: must be interruptible */
|
/* Note 2: must be interruptible */
|
||||||
|
Loading…
Reference in New Issue
Block a user