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:
Denys Vlasenko 2010-05-20 03:39:43 +02:00
parent 40477e2fdb
commit b131ccec9c

View File

@ -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 */