diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 03:39:43 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 03:39:43 +0200 |
| commit | b131ccec9c917efd735a353cb0f2cb14862192f1 (patch) | |
| tree | 96579954c233b54efbf39becc5642fb263e26709 /shell | |
| parent | 40477e2fdb3d32f4d368ee4f7c72ded4a2398082 (diff) | |
| download | busybox-w32-b131ccec9c917efd735a353cb0f2cb14862192f1.tar.gz busybox-w32-b131ccec9c917efd735a353cb0f2cb14862192f1.tar.bz2 busybox-w32-b131ccec9c917efd735a353cb0f2cb14862192f1.zip | |
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>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/shell/hush.c b/shell/hush.c index 8baccf246..fcfbd06f3 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -7258,11 +7258,20 @@ static int FAST_FUNC builtin_printf(char **argv) | |||
| 7258 | } | 7258 | } |
| 7259 | #endif | 7259 | #endif |
| 7260 | 7260 | ||
| 7261 | static char **skip_dash_dash(char **argv) | ||
| 7262 | { | ||
| 7263 | argv++; | ||
| 7264 | if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0') | ||
| 7265 | argv++; | ||
| 7266 | return argv; | ||
| 7267 | } | ||
| 7268 | |||
| 7261 | static int FAST_FUNC builtin_eval(char **argv) | 7269 | static int FAST_FUNC builtin_eval(char **argv) |
| 7262 | { | 7270 | { |
| 7263 | int rcode = EXIT_SUCCESS; | 7271 | int rcode = EXIT_SUCCESS; |
| 7264 | 7272 | ||
| 7265 | if (*++argv) { | 7273 | argv = skip_dash_dash(argv); |
| 7274 | if (*argv) { | ||
| 7266 | char *str = expand_strvec_to_string(argv); | 7275 | char *str = expand_strvec_to_string(argv); |
| 7267 | /* bash: | 7276 | /* bash: |
| 7268 | * eval "echo Hi; done" ("done" is syntax error): | 7277 | * eval "echo Hi; done" ("done" is syntax error): |
| @@ -7277,7 +7286,10 @@ static int FAST_FUNC builtin_eval(char **argv) | |||
| 7277 | 7286 | ||
| 7278 | static int FAST_FUNC builtin_cd(char **argv) | 7287 | static int FAST_FUNC builtin_cd(char **argv) |
| 7279 | { | 7288 | { |
| 7280 | const char *newdir = argv[1]; | 7289 | const char *newdir; |
| 7290 | |||
| 7291 | argv = skip_dash_dash(argv); | ||
| 7292 | newdir = argv[0]; | ||
| 7281 | if (newdir == NULL) { | 7293 | if (newdir == NULL) { |
| 7282 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, | 7294 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, |
| 7283 | * bash says "bash: cd: HOME not set" and does nothing | 7295 | * bash says "bash: cd: HOME not set" and does nothing |
| @@ -7301,7 +7313,8 @@ static int FAST_FUNC builtin_cd(char **argv) | |||
| 7301 | 7313 | ||
| 7302 | static int FAST_FUNC builtin_exec(char **argv) | 7314 | static int FAST_FUNC builtin_exec(char **argv) |
| 7303 | { | 7315 | { |
| 7304 | if (*++argv == NULL) | 7316 | argv = skip_dash_dash(argv); |
| 7317 | if (argv[0] == NULL) | ||
| 7305 | return EXIT_SUCCESS; /* bash does this */ | 7318 | return EXIT_SUCCESS; /* bash does this */ |
| 7306 | 7319 | ||
| 7307 | /* Careful: we can end up here after [v]fork. Do not restore | 7320 | /* Careful: we can end up here after [v]fork. Do not restore |
| @@ -7334,12 +7347,13 @@ static int FAST_FUNC builtin_exit(char **argv) | |||
| 7334 | */ | 7347 | */ |
| 7335 | 7348 | ||
| 7336 | /* note: EXIT trap is run by hush_exit */ | 7349 | /* note: EXIT trap is run by hush_exit */ |
| 7337 | if (*++argv == NULL) | 7350 | argv = skip_dash_dash(argv); |
| 7351 | if (argv[0] == NULL) | ||
| 7338 | hush_exit(G.last_exitcode); | 7352 | hush_exit(G.last_exitcode); |
| 7339 | /* mimic bash: exit 123abc == exit 255 + error msg */ | 7353 | /* mimic bash: exit 123abc == exit 255 + error msg */ |
| 7340 | xfunc_error_retval = 255; | 7354 | xfunc_error_retval = 255; |
| 7341 | /* bash: exit -2 == exit 254, no error msg */ | 7355 | /* bash: exit -2 == exit 254, no error msg */ |
| 7342 | hush_exit(xatoi(*argv) & 0xff); | 7356 | hush_exit(xatoi(argv[0]) & 0xff); |
| 7343 | } | 7357 | } |
| 7344 | 7358 | ||
| 7345 | static void print_escaped(const char *s) | 7359 | static void print_escaped(const char *s) |
| @@ -7668,7 +7682,7 @@ static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) | |||
| 7668 | "------------------\n"); | 7682 | "------------------\n"); |
| 7669 | for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) { | 7683 | for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) { |
| 7670 | if (x->b_descr) | 7684 | if (x->b_descr) |
| 7671 | printf("%s\t%s\n", x->b_cmd, x->b_descr); | 7685 | printf("%-10s%s\n", x->b_cmd, x->b_descr); |
| 7672 | } | 7686 | } |
| 7673 | bb_putchar('\n'); | 7687 | bb_putchar('\n'); |
| 7674 | return EXIT_SUCCESS; | 7688 | return EXIT_SUCCESS; |
| @@ -7851,8 +7865,9 @@ static int FAST_FUNC builtin_set(char **argv) | |||
| 7851 | static int FAST_FUNC builtin_shift(char **argv) | 7865 | static int FAST_FUNC builtin_shift(char **argv) |
| 7852 | { | 7866 | { |
| 7853 | int n = 1; | 7867 | int n = 1; |
| 7854 | if (argv[1]) { | 7868 | argv = skip_dash_dash(argv); |
| 7855 | n = atoi(argv[1]); | 7869 | if (argv[0]) { |
| 7870 | n = atoi(argv[0]); | ||
| 7856 | } | 7871 | } |
| 7857 | if (n >= 0 && n < G.global_argc) { | 7872 | if (n >= 0 && n < G.global_argc) { |
| 7858 | if (G.global_args_malloced) { | 7873 | if (G.global_args_malloced) { |
| @@ -7877,12 +7892,13 @@ static int FAST_FUNC builtin_source(char **argv) | |||
| 7877 | smallint sv_flg; | 7892 | smallint sv_flg; |
| 7878 | #endif | 7893 | #endif |
| 7879 | 7894 | ||
| 7880 | arg_path = NULL; | 7895 | argv = skip_dash_dash(argv); |
| 7881 | filename = *++argv; | 7896 | filename = argv[0]; |
| 7882 | if (!filename) { | 7897 | if (!filename) { |
| 7883 | /* bash says: "bash: .: filename argument required" */ | 7898 | /* bash says: "bash: .: filename argument required" */ |
| 7884 | return 2; /* bash compat */ | 7899 | return 2; /* bash compat */ |
| 7885 | } | 7900 | } |
| 7901 | arg_path = NULL; | ||
| 7886 | if (!strchr(filename, '/')) { | 7902 | if (!strchr(filename, '/')) { |
| 7887 | arg_path = find_in_path(filename); | 7903 | arg_path = find_in_path(filename); |
| 7888 | if (arg_path) | 7904 | if (arg_path) |
| @@ -7920,11 +7936,12 @@ static int FAST_FUNC builtin_umask(char **argv) | |||
| 7920 | mode_t mask; | 7936 | mode_t mask; |
| 7921 | 7937 | ||
| 7922 | mask = umask(0); | 7938 | mask = umask(0); |
| 7923 | if (argv[1]) { | 7939 | argv = skip_dash_dash(argv); |
| 7940 | if (argv[0]) { | ||
| 7924 | mode_t old_mask = mask; | 7941 | mode_t old_mask = mask; |
| 7925 | 7942 | ||
| 7926 | mask ^= 0777; | 7943 | mask ^= 0777; |
| 7927 | rc = bb_parse_mode(argv[1], &mask); | 7944 | rc = bb_parse_mode(argv[0], &mask); |
| 7928 | mask ^= 0777; | 7945 | mask ^= 0777; |
| 7929 | if (rc == 0) { | 7946 | if (rc == 0) { |
| 7930 | mask = old_mask; | 7947 | mask = old_mask; |
| @@ -7932,7 +7949,7 @@ static int FAST_FUNC builtin_umask(char **argv) | |||
| 7932 | * bash: umask: 'q': invalid symbolic mode operator | 7949 | * bash: umask: 'q': invalid symbolic mode operator |
| 7933 | * bash: umask: 999: octal number out of range | 7950 | * bash: umask: 999: octal number out of range |
| 7934 | */ | 7951 | */ |
| 7935 | bb_error_msg("%s: '%s' invalid mode", argv[0], argv[1]); | 7952 | bb_error_msg("umask: '%s' invalid mode", argv[0]); |
| 7936 | } | 7953 | } |
| 7937 | } else { | 7954 | } else { |
| 7938 | rc = 1; | 7955 | rc = 1; |
| @@ -7988,7 +8005,8 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
| 7988 | int ret = EXIT_SUCCESS; | 8005 | int ret = EXIT_SUCCESS; |
| 7989 | int status, sig; | 8006 | int status, sig; |
| 7990 | 8007 | ||
| 7991 | if (*++argv == NULL) { | 8008 | argv = skip_dash_dash(argv); |
| 8009 | if (argv[0] == NULL) { | ||
| 7992 | /* Don't care about wait results */ | 8010 | /* Don't care about wait results */ |
| 7993 | /* Note 1: must wait until there are no more children */ | 8011 | /* Note 1: must wait until there are no more children */ |
| 7994 | /* Note 2: must be interruptible */ | 8012 | /* Note 2: must be interruptible */ |
