aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-24 13:22:47 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-24 13:22:47 +0000
commitcd65fcb0f422f2caea70ff39848d7b6466c5396a (patch)
treeb14078bad2688b4857df720a3766b0f6c0d3ed61
parentff71de82651c5427c4de65a151a4ed9e21f2f1a5 (diff)
downloadbusybox-w32-cd65fcb0f422f2caea70ff39848d7b6466c5396a.tar.gz
busybox-w32-cd65fcb0f422f2caea70ff39848d7b6466c5396a.tar.bz2
busybox-w32-cd65fcb0f422f2caea70ff39848d7b6466c5396a.zip
hush: fix segfaulting syntax error in interactive hush
git-svn-id: svn://busybox.net/trunk/busybox@18684 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--shell/hush.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 1ff7b0df6..d96615d54 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -305,8 +305,8 @@ struct in_str {
305 char eof_flag; /* meaningless if ->p == NULL */ 305 char eof_flag; /* meaningless if ->p == NULL */
306 char peek_buf[2]; 306 char peek_buf[2];
307#if ENABLE_HUSH_INTERACTIVE 307#if ENABLE_HUSH_INTERACTIVE
308 int __promptme; 308 smallint promptme;
309 int promptmode; 309 smallint promptmode; /* 0: PS1, 1: PS2 */
310#endif 310#endif
311 FILE *file; 311 FILE *file;
312 int (*get) (struct in_str *); 312 int (*get) (struct in_str *);
@@ -427,15 +427,23 @@ enum { run_list_level = 0 };
427/* Normal */ 427/* Normal */
428static void syntax(const char *msg) 428static void syntax(const char *msg)
429{ 429{
430 (interactive_fd ? bb_error_msg : bb_error_msg_and_die) 430 /* Was using fancy stuff:
431 (msg ? "%s: %s" : "syntax error", "syntax error", msg); 431 * (interactive_fd ? bb_error_msg : bb_error_msg_and_die)(...params...)
432 * but it SEGVs. ?! Oh well... explicit temp ptr works around that */
433 void (*fp)(const char *s, ...);
434
435 fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die);
436 fp(msg ? "%s: %s" : "syntax error", "syntax error", msg);
432} 437}
438
433#else 439#else
434/* Debug */ 440/* Debug */
435static void syntax_lineno(int line) 441static void syntax_lineno(int line)
436{ 442{
437 (interactive_fd ? bb_error_msg : bb_error_msg_and_die) 443 void (*fp)(const char *s, ...);
438 ("syntax error hush.c:%d", line); 444
445 fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die);
446 fp("syntax error hush.c:%d", line);
439} 447}
440#define syntax(str) syntax_lineno(__LINE__) 448#define syntax(str) syntax_lineno(__LINE__)
441#endif 449#endif
@@ -1136,20 +1144,17 @@ static const char* setup_prompt_string(int promptmode)
1136 debug_printf("setup_prompt_string %d ", promptmode); 1144 debug_printf("setup_prompt_string %d ", promptmode);
1137#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT 1145#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
1138 /* Set up the prompt */ 1146 /* Set up the prompt */
1139 if (promptmode == 1) { 1147 if (promptmode == 0) { /* PS1 */
1140 char *ns;
1141 free((char*)PS1); 1148 free((char*)PS1);
1142 ns = xmalloc(strlen(cwd)+4); 1149 PS1 = xasprintf("%s %c ", cwd, (geteuid() != 0) ? '$' : '#');
1143 sprintf(ns, "%s %s", cwd, (geteuid() != 0) ? "$ " : "# "); 1150 prompt_str = PS1;
1144 prompt_str = ns;
1145 PS1 = ns;
1146 } else { 1151 } else {
1147 prompt_str = PS2; 1152 prompt_str = PS2;
1148 } 1153 }
1149#else 1154#else
1150 prompt_str = (promptmode == 1) ? PS1 : PS2; 1155 prompt_str = (promptmode == 0) ? PS1 : PS2;
1151#endif 1156#endif
1152 debug_printf("result %s\n", prompt_str); 1157 debug_printf("result '%s'\n", prompt_str);
1153 return prompt_str; 1158 return prompt_str;
1154} 1159}
1155 1160
@@ -1199,12 +1204,12 @@ static int file_get(struct in_str *i)
1199 /* need to double check i->file because we might be doing something 1204 /* need to double check i->file because we might be doing something
1200 * more complicated by now, like sourcing or substituting. */ 1205 * more complicated by now, like sourcing or substituting. */
1201#if ENABLE_HUSH_INTERACTIVE 1206#if ENABLE_HUSH_INTERACTIVE
1202 if (interactive_fd && i->__promptme && i->file == stdin) { 1207 if (interactive_fd && i->promptme && i->file == stdin) {
1203 do { 1208 do {
1204 get_user_input(i); 1209 get_user_input(i);
1205 } while (!*i->p); /* need non-empty line */ 1210 } while (!*i->p); /* need non-empty line */
1206 i->promptmode = 2; 1211 i->promptmode = 1; /* PS2 */
1207 i->__promptme = 0; 1212 i->promptme = 0;
1208 goto take_cached; 1213 goto take_cached;
1209 } 1214 }
1210#endif 1215#endif
@@ -1213,7 +1218,7 @@ static int file_get(struct in_str *i)
1213 debug_printf("file_get: got a '%c' %d\n", ch, ch); 1218 debug_printf("file_get: got a '%c' %d\n", ch, ch);
1214#if ENABLE_HUSH_INTERACTIVE 1219#if ENABLE_HUSH_INTERACTIVE
1215 if (ch == '\n') 1220 if (ch == '\n')
1216 i->__promptme = 1; 1221 i->promptme = 1;
1217#endif 1222#endif
1218 return ch; 1223 return ch;
1219} 1224}
@@ -1243,8 +1248,8 @@ static void setup_file_in_str(struct in_str *i, FILE *f)
1243 i->peek = file_peek; 1248 i->peek = file_peek;
1244 i->get = file_get; 1249 i->get = file_get;
1245#if ENABLE_HUSH_INTERACTIVE 1250#if ENABLE_HUSH_INTERACTIVE
1246 i->__promptme = 1; 1251 i->promptme = 1;
1247 i->promptmode = 1; 1252 i->promptmode = 0; /* PS1 */
1248#endif 1253#endif
1249 i->file = f; 1254 i->file = f;
1250 i->p = NULL; 1255 i->p = NULL;
@@ -1255,8 +1260,8 @@ static void setup_string_in_str(struct in_str *i, const char *s)
1255 i->peek = static_peek; 1260 i->peek = static_peek;
1256 i->get = static_get; 1261 i->get = static_get;
1257#if ENABLE_HUSH_INTERACTIVE 1262#if ENABLE_HUSH_INTERACTIVE
1258 i->__promptme = 1; 1263 i->promptme = 1;
1259 i->promptmode = 1; 1264 i->promptmode = 0; /* PS1 */
1260#endif 1265#endif
1261 i->p = s; 1266 i->p = s;
1262 i->eof_flag = 0; 1267 i->eof_flag = 0;
@@ -3246,6 +3251,7 @@ static int parse_group(o_string *dest, struct p_context *ctx,
3246 child->subshell = 1; 3251 child->subshell = 1;
3247 } 3252 }
3248 rcode = parse_stream(dest, &sub, input, endch); 3253 rcode = parse_stream(dest, &sub, input, endch);
3254//vda: err chk?
3249 done_word(dest, &sub); /* finish off the final word in the subcontext */ 3255 done_word(dest, &sub); /* finish off the final word in the subcontext */
3250 done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */ 3256 done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */
3251 child->group = sub.list_head; 3257 child->group = sub.list_head;
@@ -3588,7 +3594,7 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
3588 if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING)) 3594 if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING))
3589 set_in_charmap(";$&|", CHAR_ORDINARY); 3595 set_in_charmap(";$&|", CHAR_ORDINARY);
3590#if ENABLE_HUSH_INTERACTIVE 3596#if ENABLE_HUSH_INTERACTIVE
3591 inp->promptmode = 1; 3597 inp->promptmode = 0; /* PS1 */
3592#endif 3598#endif
3593 /* We will stop & execute after each ';' or '\n'. 3599 /* We will stop & execute after each ';' or '\n'.
3594 * Example: "sleep 9999; echo TEST" + ctrl-C: 3600 * Example: "sleep 9999; echo TEST" + ctrl-C: