This is synced from dash-0.4.17 and full ready for insert to new busybox
version:
ftp://ftp.simtreas.ru/pub/my/bb/new

News:

- code is smalest!
- support ${var...} expr
- used new very strongly steal controlling terminal
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index 843f73f..7170672 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -9,7 +9,7 @@
  *      Adam Rogoyski    <rogoyski@cs.utexas.edu>
  *      Dave Cinege      <dcinege@psychosis.com>
  *      Jakub Jelinek (c) 1995
- *      Erik Andersen    <andersen@codepoet.org> (Majorly adjusted for busybox)
+ *      Erik Andersen    <andersee@debian.org> (Majorly adjusted for busybox)
  *
  * This code is 'as is' with no warranty.
  *
@@ -63,7 +63,7 @@
 
 #define D(x)  x
 
-#endif							/* TEST */
+#endif                                                  /* TEST */
 
 #ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
 #include <dirent.h>
@@ -86,7 +86,7 @@
 #       else
 #               include <pwd.h>
 #       endif  /* TEST */
-#endif							/* advanced FEATURES */
+#endif                                                  /* advanced FEATURES */
 
 
 /* Maximum length of the linked list for the command line history */
@@ -115,30 +115,30 @@
 
 
 static
-volatile int cmdedit_termw = 80;	/* actual terminal width */
+volatile int cmdedit_termw = 80;        /* actual terminal width */
 static
-volatile int handlers_sets = 0;	/* Set next bites: */
+volatile int handlers_sets = 0; /* Set next bites: */
 
 enum {
-	SET_ATEXIT = 1,		/* when atexit() has been called 
+	SET_ATEXIT = 1,         /* when atexit() has been called
 				   and get euid,uid,gid to fast compare */
 	SET_WCHG_HANDLERS = 2,  /* winchg signal handler */
 	SET_RESET_TERM = 4,     /* if the terminal needs to be reset upon exit */
 };
 
 
-static int cmdedit_x;		/* real x terminal position */
-static int cmdedit_y;		/* pseudoreal y terminal position */
-static int cmdedit_prmt_len;	/* lenght prompt without colores string */
+static int cmdedit_x;           /* real x terminal position */
+static int cmdedit_y;           /* pseudoreal y terminal position */
+static int cmdedit_prmt_len;    /* lenght prompt without colores string */
 
-static int cursor;		/* required global for signal handler */
-static int len;			/* --- "" - - "" - -"- --""-- --""--- */
-static char *command_ps;	/* --- "" - - "" - -"- --""-- --""--- */
+static int cursor;              /* required global for signal handler */
+static int len;                 /* --- "" - - "" - -"- --""-- --""--- */
+static char *command_ps;        /* --- "" - - "" - -"- --""-- --""--- */
 static
 #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
 	const
 #endif
-char *cmdedit_prompt;		/* --- "" - - "" - -"- --""-- --""--- */
+char *cmdedit_prompt;           /* --- "" - - "" - -"- --""-- --""--- */
 
 #ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR
 static char *user_buf = "";
@@ -161,31 +161,36 @@
 static int my_uid;
 static int my_gid;
 
-#endif	/* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
+#endif  /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
+
+/* It seems that libc5 doesn't know what a sighandler_t is... */
+#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)
+typedef void (*sighandler_t) (int);
+#endif
 
 static void cmdedit_setwidth(int w, int redraw_flg);
 
 static void win_changed(int nsig)
 {
 	struct winsize win = { 0, 0, 0, 0 };
-	static sighandler_t previous_SIGWINCH_handler;	/* for reset */
+	static sighandler_t previous_SIGWINCH_handler;  /* for reset */
 
 	/*   emulate      || signal call */
 	if (nsig == -SIGWINCH || nsig == SIGWINCH) {
 		ioctl(0, TIOCGWINSZ, &win);
 		if (win.ws_col > 0) {
 			cmdedit_setwidth(win.ws_col, nsig == SIGWINCH);
-		} 
+		}
 	}
 	/* Unix not all standart in recall signal */
 
-	if (nsig == -SIGWINCH)		/* save previous handler   */
+	if (nsig == -SIGWINCH)          /* save previous handler   */
 		previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
-	else if (nsig == SIGWINCH)	/* signaled called handler */
-		signal(SIGWINCH, win_changed);	/* set for next call       */
-	else						/* nsig == 0 */
+	else if (nsig == SIGWINCH)      /* signaled called handler */
+		signal(SIGWINCH, win_changed);  /* set for next call       */
+	else                                            /* nsig == 0 */
 		/* set previous handler    */
-		signal(SIGWINCH, previous_SIGWINCH_handler);	/* reset    */
+		signal(SIGWINCH, previous_SIGWINCH_handler);    /* reset    */
 }
 
 static void cmdedit_reset_term(void)
@@ -211,9 +216,9 @@
 	int c = (int)((unsigned char) command_ps[cursor]);
 
 	if (c == 0)
-		c = ' ';	/* destroy end char? */
+		c = ' ';        /* destroy end char? */
 #ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
-	if (!Isprint(c)) {	/* Inverse put non-printable characters */
+	if (!Isprint(c)) {      /* Inverse put non-printable characters */
 		if (c >= 128)
 			c -= 128;
 		if (c < ' ')
@@ -270,9 +275,9 @@
 {
 	if (num > cursor)
 		num = cursor;
-	cursor -= num;		/* new cursor (in command, not terminal) */
+	cursor -= num;          /* new cursor (in command, not terminal) */
 
-	if (cmdedit_x >= num) {		/* no to up line */
+	if (cmdedit_x >= num) {         /* no to up line */
 		cmdedit_x -= num;
 		if (num < 4)
 			while (num-- > 0)
@@ -284,22 +289,22 @@
 		int count_y;
 
 		if (cmdedit_x) {
-			putchar('\r');		/* back to first terminal pos.  */
-			num -= cmdedit_x;	/* set previous backward        */
+			putchar('\r');          /* back to first terminal pos.  */
+			num -= cmdedit_x;       /* set previous backward        */
 		}
 		count_y = 1 + num / cmdedit_termw;
 		printf("\033[%dA", count_y);
 		cmdedit_y -= count_y;
 		/*  require  forward  after  uping   */
 		cmdedit_x = cmdedit_termw * count_y - num;
-		printf("\033[%dC", cmdedit_x);	/* set term cursor   */
+		printf("\033[%dC", cmdedit_x);  /* set term cursor   */
 	}
 }
 
 static void put_prompt(void)
 {
 	out1str(cmdedit_prompt);
-	cmdedit_x = cmdedit_prmt_len;	/* count real x terminal position */
+	cmdedit_x = cmdedit_prmt_len;   /* count real x terminal position */
 	cursor = 0;
 	cmdedit_y = 0;                  /* new quasireal y */
 }
@@ -335,7 +340,7 @@
 		if (c == '\\') {
 			const char *cp = prmt_ptr;
 			int l;
-			
+
 			c = bb_process_escape_sequence(&prmt_ptr);
 			if(prmt_ptr==cp) {
 			  if (*cp == 0)
@@ -346,7 +351,7 @@
 			  case 'u':
 				pbuf = user_buf;
 				break;
-#endif	
+#endif
 			  case 'h':
 				pbuf = hostname_buf;
 				if (pbuf == 0) {
@@ -378,7 +383,7 @@
 					strcpy(pbuf+1, pwd_buf+l);
 					}
 				break;
-#endif	
+#endif
 			  case 'W':
 				pbuf = pwd_buf;
 				cp = strrchr(pbuf,'/');
@@ -391,7 +396,7 @@
 			  case 'e': case 'E':     /* \e \E = \033 */
 				c = '\033';
 				break;
-			  case 'x': case 'X': 
+			  case 'x': case 'X':
 				for (l = 0; l < 3;) {
 					int h;
 					buf2[l++] = *prmt_ptr;
@@ -416,7 +421,7 @@
 				}
 				break;
 			  }
-			} 
+			}
 		}
 		if(pbuf == buf)
 			*pbuf = c;
@@ -437,12 +442,12 @@
 /* draw promt, editor line, and clear tail */
 static void redraw(int y, int back_cursor)
 {
-	if (y > 0)				/* up to start y */
+	if (y > 0)                              /* up to start y */
 		printf("\033[%dA", y);
 	putchar('\r');
 	put_prompt();
-	input_end();				/* rewrite */
-	printf("\033[J");			/* destroy tail after cursor */
+	input_end();                            /* rewrite */
+	printf("\033[J");                       /* destroy tail after cursor */
 	input_backward(back_cursor);
 }
 
@@ -456,9 +461,9 @@
 
 	strcpy(command_ps + j, command_ps + j + 1);
 	len--;
-	input_end();			/* rewtite new line */
-	cmdedit_set_out_char(0);	/* destroy end char */
-	input_backward(cursor - j);	/* back to old pos cursor */
+	input_end();                    /* rewtite new line */
+	cmdedit_set_out_char(0);        /* destroy end char */
+	input_backward(cursor - j);     /* back to old pos cursor */
 }
 
 /* Delete the char in back of the cursor */
@@ -496,7 +501,7 @@
 			redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
 			fflush(stdout);
 		}
-	} 
+	}
 }
 
 static void cmdedit_init(void)
@@ -527,9 +532,9 @@
 #endif
 		my_uid = getuid();
 		my_gid = getgid();
-#endif	/* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
+#endif  /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
 		handlers_sets |= SET_ATEXIT;
-		atexit(cmdedit_reset_term);	/* be sure to do this only once */
+		atexit(cmdedit_reset_term);     /* be sure to do this only once */
 	}
 }
 
@@ -553,35 +558,35 @@
 	char *temp;
 
 
-	ud++;				/* ~user/... to user/... */
+	ud++;                           /* ~user/... to user/... */
 	userlen = strlen(ud);
 
-	if (num_matches == 0) {		/* "~/..." or "~user/..." */
+	if (num_matches == 0) {         /* "~/..." or "~user/..." */
 		char *sav_ud = ud - 1;
 		char *home = 0;
 
-		if (*ud == '/') {	/* "~/..."     */
+		if (*ud == '/') {       /* "~/..."     */
 			home = home_pwd_buf;
 		} else {
 			/* "~user/..." */
 			temp = strchr(ud, '/');
-			*temp = 0;		/* ~user\0 */
+			*temp = 0;              /* ~user\0 */
 			entry = getpwnam(ud);
-			*temp = '/';		/* restore ~user/... */
+			*temp = '/';            /* restore ~user/... */
 			ud = temp;
 			if (entry)
 				home = entry->pw_dir;
 		}
 		if (home) {
 			if ((userlen + strlen(home) + 1) < BUFSIZ) {
-				char temp2[BUFSIZ];	/* argument size */
+				char temp2[BUFSIZ];     /* argument size */
 
 				/* /home/user/... */
 				sprintf(temp2, "%s%s", home, ud);
 				strcpy(sav_ud, temp2);
 			}
 		}
-		return 0;	/* void, result save to argument :-) */
+		return 0;       /* void, result save to argument :-) */
 	} else {
 		/* "~[^/]*" */
 		char **matches = (char **) NULL;
@@ -593,7 +598,7 @@
 			/* Null usernames should result in all users as possible completions. */
 			if ( /*!userlen || */ !strncmp(ud, entry->pw_name, userlen)) {
 
-                               bb_xasprintf(&temp, "~%s/", entry->pw_name);
+			       bb_xasprintf(&temp, "~%s/", entry->pw_name);
 				matches = xrealloc(matches, (nm + 1) * sizeof(char *));
 
 				matches[nm++] = temp;
@@ -605,7 +610,7 @@
 		return (matches);
 	}
 }
-#endif	/* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */
+#endif  /* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */
 
 enum {
 	FIND_EXE_ONLY = 0,
@@ -630,11 +635,11 @@
 	npth = 0;
 
 	for (;;) {
-		npth++;			/* count words is + 1 count ':' */
+		npth++;                 /* count words is + 1 count ':' */
 		tmp = strchr(tmp, ':');
 		if (tmp) {
 			if (*++tmp == 0)
-				break;	/* :<empty> */
+				break;  /* :<empty> */
 		} else
 			break;
 	}
@@ -643,17 +648,17 @@
 
 	tmp = pth;
 	(*p)[0] = bb_xstrdup(tmp);
-	npth = 1;			/* count words is + 1 count ':' */
+	npth = 1;                       /* count words is + 1 count ':' */
 
 	for (;;) {
 		tmp = strchr(tmp, ':');
 		if (tmp) {
-			(*p)[0][(tmp - pth)] = 0;	/* ':' -> '\0' */
+			(*p)[0][(tmp - pth)] = 0;       /* ':' -> '\0' */
 			if (*++tmp == 0)
-				break;			/* :<empty> */
+				break;                  /* :<empty> */
 		} else
 			break;
-		(*p)[npth++] = &(*p)[0][(tmp - pth)];	/* p[next]=p[0][&'\0'+1] */
+		(*p)[npth++] = &(*p)[0][(tmp - pth)];   /* p[next]=p[0][&'\0'+1] */
 	}
 
 	return npth;
@@ -703,20 +708,20 @@
 		/* set dir only */
 		dirbuf[(pfind - command) + 1] = 0;
 #ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION
-		if (dirbuf[0] == '~')	/* ~/... or ~user/... */
+		if (dirbuf[0] == '~')   /* ~/... or ~user/... */
 			username_tab_completion(dirbuf, 0);
 #endif
 		/* "strip" dirname in command */
 		pfind++;
 
 		paths[0] = dirbuf;
-		npaths = 1;				/* only 1 dir */
+		npaths = 1;                             /* only 1 dir */
 	}
 
 	for (i = 0; i < npaths; i++) {
 
 		dir = opendir(paths[i]);
-		if (!dir)			/* Don't print an error */
+		if (!dir)                       /* Don't print an error */
 			continue;
 
 		while ((next = readdir(dir)) != NULL) {
@@ -728,17 +733,17 @@
 			/* not see .name without .match */
 			if (*str_found == '.' && *pfind == 0) {
 				if (*paths[i] == '/' && paths[i][1] == 0
-					&& str_found[1] == 0) str_found = "";	/* only "/" */
+					&& str_found[1] == 0) str_found = "";   /* only "/" */
 				else
 					continue;
 			}
 			found = concat_path_file(paths[i], str_found);
 			/* hmm, remover in progress? */
-			if (stat(found, &st) < 0) 
+			if (stat(found, &st) < 0)
 				goto cont;
 			/* find with dirs ? */
 			if (paths[i] != dirbuf)
-				strcpy(found, next->d_name);	/* only name */
+				strcpy(found, next->d_name);    /* only name */
 			if (S_ISDIR(st.st_mode)) {
 				/* name is directory      */
 				str_found = found;
@@ -747,7 +752,7 @@
 				str_found = add_quote_for_spec_chars(found);
 			} else {
 				/* not put found file if search only dirs for cd */
-				if (type == FIND_DIR_ONLY) 
+				if (type == FIND_DIR_ONLY)
 					goto cont;
 				str_found = add_quote_for_spec_chars(found);
 				if (type == FIND_FILE_ONLY ||
@@ -764,7 +769,7 @@
 		closedir(dir);
 	}
 	if (paths != path1) {
-		free(paths[0]);			/* allocated memory only in first member */
+		free(paths[0]);                 /* allocated memory only in first member */
 		free(paths);
 	}
 	*num_matches = nm;
@@ -796,7 +801,7 @@
 	for (i = 0;; i++) {
 		int_buf[i] = (int) ((unsigned char) matchBuf[i]);
 		if (int_buf[i] == 0) {
-			pos_buf[i] = -1;	/* indicator end line */
+			pos_buf[i] = -1;        /* indicator end line */
 			break;
 		} else
 			pos_buf[i] = i;
@@ -809,7 +814,7 @@
 			int_buf[j] |= QUOT;
 			i++;
 #ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
-			if (matchBuf[i] == '\t')	/* algorithm equivalent */
+			if (matchBuf[i] == '\t')        /* algorithm equivalent */
 				int_buf[j] = ' ' | QUOT;
 #endif
 		}
@@ -852,7 +857,7 @@
 		}
 		if (command_mode) {
 			collapse_pos(0, i + command_mode);
-			i = -1;				/* hack incremet */
+			i = -1;                         /* hack incremet */
 		}
 	}
 	/* collapse `command...` */
@@ -869,11 +874,11 @@
 				collapse_pos(0, i + 1);
 				break;
 			} else
-				i--;			/* hack incremet */
+				i--;                    /* hack incremet */
 		}
 
 	/* collapse (command...(command...)...) or {command...{command...}...} */
-	c = 0;						/* "recursive" level */
+	c = 0;                                          /* "recursive" level */
 	c2 = 0;
 	for (i = 0; int_buf[i]; i++)
 		if (int_buf[i] == '(' || int_buf[i] == '{') {
@@ -882,7 +887,7 @@
 			else
 				c2++;
 			collapse_pos(0, i + 1);
-			i = -1;				/* hack incremet */
+			i = -1;                         /* hack incremet */
 		}
 	for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++)
 		if ((int_buf[i] == ')' && c > 0) || (int_buf[i] == '}' && c2 > 0)) {
@@ -891,7 +896,7 @@
 			else
 				c2--;
 			collapse_pos(0, i + 1);
-			i = -1;				/* hack incremet */
+			i = -1;                         /* hack incremet */
 		}
 
 	/* skip first not quote space */
@@ -927,7 +932,7 @@
 	/* skip first not quoted '\'' or '"' */
 	for (i = 0; int_buf[i] == '\'' || int_buf[i] == '"'; i++);
 	/* collapse quote or unquote // or /~ */
-	while ((int_buf[i] & ~QUOT) == '/' && 
+	while ((int_buf[i] & ~QUOT) == '/' &&
 			((int_buf[i + 1] & ~QUOT) == '/'
 			 || (int_buf[i + 1] & ~QUOT) == '~')) {
 		i++;
@@ -991,7 +996,7 @@
 	static int num_matches;
 	static char **matches;
 
-	if (lastWasTab == 0) {		/* free all memory */
+	if (lastWasTab == 0) {          /* free all memory */
 		if (matches) {
 			while (num_matches > 0)
 				free(matches[--num_matches]);
@@ -1008,7 +1013,7 @@
 		int find_type;
 		int recalc_pos;
 
-		*lastWasTab = TRUE;		/* flop trigger */
+		*lastWasTab = TRUE;             /* flop trigger */
 
 		/* Make a local copy of the string -- up
 		 * to the position of the cursor */
@@ -1061,7 +1066,7 @@
 
 			beep();
 			if (!matches)
-				return;		/* not found */
+				return;         /* not found */
 			/* sort */
 			qsort(matches, num_matches, sizeof(char *), match_compare);
 
@@ -1073,11 +1078,11 @@
 						*tmp1 = 0;
 						break;
 					}
-			if (*tmp == 0) {	/* have unique */
+			if (*tmp == 0) {        /* have unique */
 				free(tmp);
 				return;
 			}
-		} else {			/* one match */
+		} else {                        /* one match */
 			tmp = matches[0];
 			/* for next completion current found */
 			*lastWasTab = FALSE;
@@ -1111,7 +1116,7 @@
 		 * just hit TAB again, print a list of all the
 		 * available choices... */
 		if (matches && num_matches > 0) {
-			int sav_cursor = cursor;	/* change goto_new_line() */
+			int sav_cursor = cursor;        /* change goto_new_line() */
 
 			/* Go to the next line */
 			goto_new_line();
@@ -1120,7 +1125,7 @@
 		}
 	}
 }
-#endif	/* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
+#endif  /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
 
 #if MAX_HISTORY >= 1
 static void get_previous_history(void)
@@ -1159,7 +1164,7 @@
 	}
 
 	if (( fp = fopen ( fromfile, "r" ))) {
-	
+
 		for ( hi = 0; hi < MAX_HISTORY; ) {
 			char * hl = bb_get_chomped_line_from_file(fp);
 			int l;
@@ -1183,10 +1188,10 @@
 extern void save_history ( const char *tofile )
 {
 	FILE *fp = fopen ( tofile, "w" );
-	
+
 	if ( fp ) {
 		int i;
-		
+
 		for ( i = 0; i < n_history; i++ ) {
 			fputs ( history [i], fp );
 			fputc ( '\n', fp );
@@ -1220,7 +1225,7 @@
  * Furthermore, the "vi" command editing keys are not implemented.
  *
  */
- 
+
 
 int cmdedit_read_input(char *prompt, char command[BUFSIZ])
 {
@@ -1230,7 +1235,7 @@
 	unsigned char c = 0;
 
 	/* prepare before init handlers */
-	cmdedit_y = 0;	/* quasireal y, not true work if line > xt*yt */
+	cmdedit_y = 0;  /* quasireal y, not true work if line > xt*yt */
 	len = 0;
 	command_ps = command;
 
@@ -1247,7 +1252,7 @@
 #       ifndef _POSIX_VDISABLE
 #               define _POSIX_VDISABLE '\0'
 #       endif
-	new_settings.c_cc[VINTR] = _POSIX_VDISABLE;	
+	new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
 #endif
 	command[0] = 0;
 
@@ -1261,7 +1266,7 @@
 
 	while (1) {
 
-		fflush(stdout);			/* buffered out to fast */
+		fflush(stdout);                 /* buffered out to fast */
 
 		if (safe_read(0, &c, 1) < 1)
 			/* if we can't read input then exit */
@@ -1287,8 +1292,12 @@
 			goto_new_line();
 			command[0] = 0;
 			len = 0;
+#if !defined(CONFIG_ASH)
 			lastWasTab = FALSE;
 			put_prompt();
+#else
+			break_out = 2;
+#endif
 			break;
 		case 4:
 			/* Control-d -- Delete one character, or exit
@@ -1327,14 +1336,14 @@
 #endif
 			break;
 		case 11:
-			/* Control-k -- clear to end of line */  
+			/* Control-k -- clear to end of line */
 			*(command + cursor) = 0;
 			len = cursor;
 			printf("\033[J");
 			break;
-		case 12: 
+		case 12:
 				/* Control-l -- clear screen */
-				printf("\033[H");
+			printf("\033[H");
 			redraw(0, len-cursor);
 			break;
 #if MAX_HISTORY >= 1
@@ -1371,7 +1380,7 @@
 			}
 			switch (c) {
 #ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
-			case '\t':			/* Alt-Tab */
+			case '\t':                      /* Alt-Tab */
 
 				input_tab(&lastWasTab);
 				break;
@@ -1433,7 +1442,7 @@
 			break;
 		}
 
-		default:	/* If it's regular input, do the normal thing */
+		default:        /* If it's regular input, do the normal thing */
 #ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
 			/* Control-V -- Add non-printable symbol */
 			if (c == 22) {
@@ -1445,19 +1454,19 @@
 				}
 			} else
 #endif
-			if (!Isprint(c))	/* Skip non-printable characters */
+			if (!Isprint(c))        /* Skip non-printable characters */
 				break;
 
-			if (len >= (BUFSIZ - 2))	/* Need to leave space for enter */
+			if (len >= (BUFSIZ - 2))        /* Need to leave space for enter */
 				break;
 
 			len++;
 
-			if (cursor == (len - 1)) {	/* Append if at the end of the line */
+			if (cursor == (len - 1)) {      /* Append if at the end of the line */
 				*(command + cursor) = c;
 				*(command + cursor + 1) = 0;
 				cmdedit_set_out_char(0);
-			} else {			/* Insert otherwise */
+			} else {                        /* Insert otherwise */
 				int sc = cursor;
 
 				memmove(command + sc + 1, command + sc, len - sc);
@@ -1471,7 +1480,7 @@
 
 			break;
 		}
-		if (break_out)			/* Enter is the command terminator, no more input. */
+		if (break_out)                  /* Enter is the command terminator, no more input. */
 			break;
 
 		if (c != '\t')
@@ -1486,7 +1495,7 @@
 	/* cleanup may be saved current command line */
 	free(history[MAX_HISTORY]);
 	history[MAX_HISTORY] = 0;
-	if (len) {					/* no put empty line */
+	if (len) {                                      /* no put empty line */
 		int i = n_history;
 			/* After max history, remove the oldest command */
 		if (i >= MAX_HISTORY) {
@@ -1508,23 +1517,27 @@
 	}
 #endif
 #endif  /* MAX_HISTORY >= 1 */
-	if(break_out>0) {
-	command[len++] = '\n';		/* set '\n' */
-	command[len] = 0;
+	if(break_out == 1) {
+		command[len++] = '\n';          /* set '\n' */
+		command[len] = 0;
 	}
 #if defined(CONFIG_FEATURE_CLEAN_UP) && defined(CONFIG_FEATURE_COMMAND_TAB_COMPLETION)
-	input_tab(0);				/* strong free */
+	input_tab(0);                           /* strong free */
 #endif
 #if defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
 	free(cmdedit_prompt);
 #endif
 	cmdedit_reset_term();
+#if !defined(CONFIG_ASH)
 	return len;
+#else
+	return break_out < 0 ? break_out : len;
+#endif
 }
 
 
 
-#endif	/* CONFIG_FEATURE_COMMAND_EDITING */
+#endif  /* CONFIG_FEATURE_COMMAND_EDITING */
 
 
 #ifdef TEST
@@ -1565,4 +1578,4 @@
 	return 0;
 }
 
-#endif	/* TEST */
+#endif  /* TEST */