svn commit: trunk/busybox/shell

vda at busybox.net vda at busybox.net
Thu May 24 13:22:47 UTC 2007


Author: vda
Date: 2007-05-24 06:22:47 -0700 (Thu, 24 May 2007)
New Revision: 18684

Log:
hush: fix segfaulting syntax error in interactive hush


Modified:
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2007-05-24 13:22:01 UTC (rev 18683)
+++ trunk/busybox/shell/hush.c	2007-05-24 13:22:47 UTC (rev 18684)
@@ -305,8 +305,8 @@
 	char eof_flag; /* meaningless if ->p == NULL */
 	char peek_buf[2];
 #if ENABLE_HUSH_INTERACTIVE
-	int __promptme;
-	int promptmode;
+	smallint promptme;
+	smallint promptmode; /* 0: PS1, 1: PS2 */
 #endif
 	FILE *file;
 	int (*get) (struct in_str *);
@@ -427,15 +427,23 @@
 /* Normal */
 static void syntax(const char *msg)
 {
-	(interactive_fd ? bb_error_msg : bb_error_msg_and_die)
-		(msg ? "%s: %s" : "syntax error", "syntax error", msg);
+	/* Was using fancy stuff:
+	 * (interactive_fd ? bb_error_msg : bb_error_msg_and_die)(...params...)
+	 * but it SEGVs. ?! Oh well... explicit temp ptr works around that */
+	void (*fp)(const char *s, ...);
+
+	fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die);
+	fp(msg ? "%s: %s" : "syntax error", "syntax error", msg);
 }
+
 #else
 /* Debug */
 static void syntax_lineno(int line)
 {
-	(interactive_fd ? bb_error_msg : bb_error_msg_and_die)
-		("syntax error hush.c:%d", line);
+	void (*fp)(const char *s, ...);
+
+	fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die);
+	fp("syntax error hush.c:%d", line);
 }
 #define syntax(str) syntax_lineno(__LINE__)
 #endif
@@ -1136,20 +1144,17 @@
 	debug_printf("setup_prompt_string %d ", promptmode);
 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
 	/* Set up the prompt */
-	if (promptmode == 1) {
-		char *ns;
+	if (promptmode == 0) { /* PS1 */
 		free((char*)PS1);
-		ns = xmalloc(strlen(cwd)+4);
-		sprintf(ns, "%s %s", cwd, (geteuid() != 0) ? "$ " : "# ");
-		prompt_str = ns;
-		PS1 = ns;
+		PS1 = xasprintf("%s %c ", cwd, (geteuid() != 0) ? '$' : '#');
+		prompt_str = PS1;
 	} else {
 		prompt_str = PS2;
 	}
 #else
-	prompt_str = (promptmode == 1) ? PS1 : PS2;
+	prompt_str = (promptmode == 0) ? PS1 : PS2;
 #endif
-	debug_printf("result %s\n", prompt_str);
+	debug_printf("result '%s'\n", prompt_str);
 	return prompt_str;
 }
 
@@ -1199,12 +1204,12 @@
 		/* need to double check i->file because we might be doing something
 		 * more complicated by now, like sourcing or substituting. */
 #if ENABLE_HUSH_INTERACTIVE
-		if (interactive_fd && i->__promptme && i->file == stdin) {
+		if (interactive_fd && i->promptme && i->file == stdin) {
 			do {
 				get_user_input(i);
 			} while (!*i->p); /* need non-empty line */
-			i->promptmode = 2;
-			i->__promptme = 0;
+			i->promptmode = 1; /* PS2 */
+			i->promptme = 0;
 			goto take_cached;
 		}
 #endif
@@ -1213,7 +1218,7 @@
 	debug_printf("file_get: got a '%c' %d\n", ch, ch);
 #if ENABLE_HUSH_INTERACTIVE
 	if (ch == '\n')
-		i->__promptme = 1;
+		i->promptme = 1;
 #endif
 	return ch;
 }
@@ -1243,8 +1248,8 @@
 	i->peek = file_peek;
 	i->get = file_get;
 #if ENABLE_HUSH_INTERACTIVE
-	i->__promptme = 1;
-	i->promptmode = 1;
+	i->promptme = 1;
+	i->promptmode = 0; /* PS1 */
 #endif
 	i->file = f;
 	i->p = NULL;
@@ -1255,8 +1260,8 @@
 	i->peek = static_peek;
 	i->get = static_get;
 #if ENABLE_HUSH_INTERACTIVE
-	i->__promptme = 1;
-	i->promptmode = 1;
+	i->promptme = 1;
+	i->promptmode = 0; /* PS1 */
 #endif
 	i->p = s;
 	i->eof_flag = 0;
@@ -3246,6 +3251,7 @@
 		child->subshell = 1;
 	}
 	rcode = parse_stream(dest, &sub, input, endch);
+//vda: err chk?
 	done_word(dest, &sub); /* finish off the final word in the subcontext */
 	done_pipe(&sub, PIPE_SEQ);  /* and the final command there, too */
 	child->group = sub.list_head;
@@ -3588,7 +3594,7 @@
 		if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING))
 			set_in_charmap(";$&|", CHAR_ORDINARY);
 #if ENABLE_HUSH_INTERACTIVE
-		inp->promptmode = 1;
+		inp->promptmode = 0; /* PS1 */
 #endif
 		/* We will stop & execute after each ';' or '\n'.
 		 * Example: "sleep 9999; echo TEST" + ctrl-C:




More information about the busybox-cvs mailing list