[git commit master] hush: support "cd -- DIR" and such

Denys Vlasenko vda.linux at googlemail.com
Thu May 20 01:39:43 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=b131ccec9c917efd735a353cb0f2cb14862192f1
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 shell/hush.c |   46 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index 8baccf2..fcfbd06 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -7258,11 +7258,20 @@ static int FAST_FUNC builtin_printf(char **argv)
 }
 #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)
 {
 	int rcode = EXIT_SUCCESS;
 
-	if (*++argv) {
+	argv = skip_dash_dash(argv);
+	if (*argv) {
 		char *str = expand_strvec_to_string(argv);
 		/* bash:
 		 * 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)
 {
-	const char *newdir = argv[1];
+	const char *newdir;
+
+	argv = skip_dash_dash(argv);
+	newdir = argv[0];
 	if (newdir == NULL) {
 		/* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
 		 * 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)
 {
-	if (*++argv == NULL)
+	argv = skip_dash_dash(argv);
+	if (argv[0] == NULL)
 		return EXIT_SUCCESS; /* bash does this */
 
 	/* 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 */
-	if (*++argv == NULL)
+	argv = skip_dash_dash(argv);
+	if (argv[0] == NULL)
 		hush_exit(G.last_exitcode);
 	/* mimic bash: exit 123abc == exit 255 + error msg */
 	xfunc_error_retval = 255;
 	/* 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)
@@ -7668,7 +7682,7 @@ static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
 		"------------------\n");
 	for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
 		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');
 	return EXIT_SUCCESS;
@@ -7851,8 +7865,9 @@ static int FAST_FUNC builtin_set(char **argv)
 static int FAST_FUNC builtin_shift(char **argv)
 {
 	int n = 1;
-	if (argv[1]) {
-		n = atoi(argv[1]);
+	argv = skip_dash_dash(argv);
+	if (argv[0]) {
+		n = atoi(argv[0]);
 	}
 	if (n >= 0 && n < G.global_argc) {
 		if (G.global_args_malloced) {
@@ -7877,12 +7892,13 @@ static int FAST_FUNC builtin_source(char **argv)
 	smallint sv_flg;
 #endif
 
-	arg_path = NULL;
-	filename = *++argv;
+	argv = skip_dash_dash(argv);
+	filename = argv[0];
 	if (!filename) {
 		/* bash says: "bash: .: filename argument required" */
 		return 2; /* bash compat */
 	}
+	arg_path = NULL;
 	if (!strchr(filename, '/')) {
 		arg_path = find_in_path(filename);
 		if (arg_path)
@@ -7920,11 +7936,12 @@ static int FAST_FUNC builtin_umask(char **argv)
 	mode_t mask;
 
 	mask = umask(0);
-	if (argv[1]) {
+	argv = skip_dash_dash(argv);
+	if (argv[0]) {
 		mode_t old_mask = mask;
 
 		mask ^= 0777;
-		rc = bb_parse_mode(argv[1], &mask);
+		rc = bb_parse_mode(argv[0], &mask);
 		mask ^= 0777;
 		if (rc == 0) {
 			mask = old_mask;
@@ -7932,7 +7949,7 @@ static int FAST_FUNC builtin_umask(char **argv)
 			 * bash: umask: 'q': invalid symbolic mode operator
 			 * 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 {
 		rc = 1;
@@ -7988,7 +8005,8 @@ static int FAST_FUNC builtin_wait(char **argv)
 	int ret = EXIT_SUCCESS;
 	int status, sig;
 
-	if (*++argv == NULL) {
+	argv = skip_dash_dash(argv);
+	if (argv[0] == NULL) {
 		/* Don't care about wait results */
 		/* Note 1: must wait until there are no more children */
 		/* Note 2: must be interruptible */
-- 
1.6.3.3



More information about the busybox-cvs mailing list