Some enhancements I've been working on over the weekend,
 -Erik
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index d15c694..9800dd1 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -53,9 +53,10 @@
 static struct history *his_end = NULL;	/* Last element in command line list */
 static struct termio old_term, new_term;	/* Current termio and the previous termio before starting ash */
 
+static int cmdedit_termw = 80;  /* actual terminal width */
+static int cmdedit_scroll = 27; /* width of EOL scrolling region */
 static int history_counter = 0;	/* Number of commands in history list */
 static int reset_term = 0;		/* Set to true if the terminal needs to be reset upon exit */
-char *parsenextc;				/* copy of parsefile->nextc */
 
 struct history {
 	char *s;
@@ -63,85 +64,42 @@
 	struct history *n;
 };
 
+#define xwrite write
 
-/* Version of write which resumes after a signal is caught.  */
-int xwrite(int fd, char *buf, int nbytes)
+void
+cmdedit_setwidth(int w)
 {
-	int ntry;
-	int i;
-	int n;
-
-	n = nbytes;
-	ntry = 0;
-	for (;;) {
-		i = write(fd, buf, n);
-		if (i > 0) {
-			if ((n -= i) <= 0)
-				return nbytes;
-			buf += i;
-			ntry = 0;
-		} else if (i == 0) {
-			if (++ntry > 10)
-				return nbytes - n;
-		} else if (errno != EINTR) {
-			return -1;
-		}
-	}
+    if (w > 20) {
+		cmdedit_termw = w;
+		cmdedit_scroll = w / 3;
+    } else {
+		errorMsg("\n*** Error: minimum screen width is 21\n");
+    }
 }
 
-
-/* Version of ioctl that retries after a signal is caught.  */
-int xioctl(int fd, unsigned long request, char *arg)
-{
-	int i;
-
-	while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
-	return i;
-}
-
-
 void cmdedit_reset_term(void)
 {
 	if (reset_term)
-		xioctl(fileno(stdin), TCSETA, (void *) &old_term);
+		ioctl(fileno(stdin), TCSETA, (void *) &old_term);
 }
 
-void prepareToDie(int sig)
+void clean_up_and_die(int sig)
 {
 	cmdedit_reset_term();
 	fprintf(stdout, "\n");
 	exit(TRUE);
 }
 
+/* Go to HOME position */
 void input_home(int outputFd, int *cursor)
-{								/* Command line input routines */
+{
 	while (*cursor > 0) {
 		xwrite(outputFd, "\b", 1);
 		--*cursor;
 	}
 }
 
-
-void input_delete(int outputFd, int cursor)
-{
-	int j = 0;
-
-	memmove(parsenextc + cursor, parsenextc + cursor + 1,
-			BUFSIZ - cursor - 1);
-	for (j = cursor; j < (BUFSIZ - 1); j++) {
-		if (!*(parsenextc + j))
-			break;
-		else
-			xwrite(outputFd, (parsenextc + j), 1);
-	}
-
-	xwrite(outputFd, " \b", 2);
-
-	while (j-- > cursor)
-		xwrite(outputFd, "\b", 1);
-}
-
-
+/* Go to END position */
 void input_end(int outputFd, int *cursor, int len)
 {
 	while (*cursor < len) {
@@ -150,22 +108,22 @@
 	}
 }
 
-
-void input_backspace(int outputFd, int *cursor, int *len)
+/* Delete the char in back of the cursor */
+void input_backspace(char* command, int outputFd, int *cursor, int *len)
 {
 	int j = 0;
 
 	if (*cursor > 0) {
 		xwrite(outputFd, "\b \b", 3);
 		--*cursor;
-		memmove(parsenextc + *cursor, parsenextc + *cursor + 1,
+		memmove(command + *cursor, command + *cursor + 1,
 				BUFSIZ - *cursor + 1);
 
 		for (j = *cursor; j < (BUFSIZ - 1); j++) {
-			if (!*(parsenextc + j))
+			if (!*(command + j))
 				break;
 			else
-				xwrite(outputFd, (parsenextc + j), 1);
+				xwrite(outputFd, (command + j), 1);
 		}
 
 		xwrite(outputFd, " \b", 2);
@@ -177,18 +135,61 @@
 	}
 }
 
-#ifdef BB_FEATURE_SH_TAB_COMPLETION
+/* Delete the char in front of the cursor */
+void input_delete(char* command, int outputFd, int cursor, int *len)
+{
+	int j = 0;
 
-char** username_completion_matches(char* command, int *num_matches)
+	if (cursor == *len)
+		return;
+	
+	memmove(command + cursor, command + cursor + 1,
+			BUFSIZ - cursor - 1);
+	for (j = cursor; j < (BUFSIZ - 1); j++) {
+		if (!*(command + j))
+			break;
+		else
+			xwrite(outputFd, (command + j), 1);
+	}
+
+	xwrite(outputFd, " \b", 2);
+
+	while (j-- > cursor)
+		xwrite(outputFd, "\b", 1);
+	--*len;
+}
+
+/* Move forward one charactor */
+void input_forward(int outputFd, int *cursor, int len)
+{
+	if (*cursor < len) {
+		xwrite(outputFd, "\033[C", 3);
+		++*cursor;
+	}
+}
+
+/* Move back one charactor */
+void input_backward(int outputFd, int *cursor)
+{
+	if (*cursor > 0) {
+		xwrite(outputFd, "\033[D", 3);
+		--*cursor;
+	}
+}
+
+
+
+#ifdef BB_FEATURE_SH_TAB_COMPLETION
+char** username_tab_completion(char* command, int *num_matches)
 {
 	char **matches = (char **) NULL;
 	*num_matches=0;
-	fprintf(stderr, "\nin username_completion_matches\n");
+	fprintf(stderr, "\nin username_tab_completion\n");
 	return (matches);
 }
 
 #include <dirent.h>
-char** find_path_executable_n_cwd_matches(char* command, int *num_matches)
+char** exe_n_cwd_tab_completion(char* command, int *num_matches)
 {
 	char *dirName;
 	char **matches = (char **) NULL;
@@ -227,6 +228,170 @@
 
 	return (matches);
 }
+
+void input_tab(char* command, int outputFd, int *cursor, int *len)
+{
+	/* Do TAB completion */
+	static int num_matches=0;
+	static char **matches = (char **) NULL;
+	int pos = cursor;
+
+
+	if (lastWasTab == FALSE) {
+		char *tmp, *tmp1, *matchBuf;
+
+		/* For now, we will not bother with trying to distinguish
+		 * whether the cursor is in/at a command extression -- we
+		 * will always try all possable matches.  If you don't like
+		 * that then feel free to fix it.
+		 */
+
+		/* Make a local copy of the string -- up 
+		 * to the position of the cursor */
+		matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
+		strncpy(matchBuf, command, cursor);
+		tmp=matchBuf;
+
+		/* skip past any command seperator tokens */
+		while (*tmp && (tmp1=strpbrk(tmp, ";|&{(`")) != NULL) {
+			tmp=++tmp1;
+			/* skip any leading white space */
+			while (*tmp && isspace(*tmp)) 
+				++tmp;
+		}
+
+		/* skip any leading white space */
+		while (*tmp && isspace(*tmp)) 
+			++tmp;
+
+		/* Free up any memory already allocated */
+		if (matches) {
+			free(matches);
+			matches = (char **) NULL;
+		}
+
+		/* If the word starts with `~' and there is no slash in the word, 
+		 * then try completing this word as a username. */
+
+		/* FIXME -- this check is broken! */
+		if (*tmp == '~' && !strchr(tmp, '/'))
+			matches = username_tab_completion(tmp, &num_matches);
+
+		/* Try to match any executable in our path and everything 
+		 * in the current working directory that matches.  */
+		if (!matches)
+			matches = exe_n_cwd_tab_completion(tmp, &num_matches);
+
+		/* Don't leak memory */
+		free( matchBuf);
+
+		/* Did we find exactly one match? */
+		if (matches && num_matches==1) {
+			/* write out the matched command */
+			strncpy(command+pos, matches[0]+pos, strlen(matches[0])-pos);
+			len=strlen(command);
+			cursor=len;
+			xwrite(outputFd, matches[0]+pos, strlen(matches[0])-pos);
+			break;
+		}
+	} else {
+		/* Ok -- the last char was a TAB.  Since they
+		 * just hit TAB again, print a list of all the
+		 * available choices... */
+		if ( matches && num_matches>0 ) {
+			int i, col;
+
+			/* Go to the next line */
+			xwrite(outputFd, "\n", 1);
+			/* Print the list of matches */
+			for (i=0,col=0; i<num_matches; i++) {
+				char foo[17];
+				sprintf(foo, "%-14s  ", matches[i]);
+				col += xwrite(outputFd, foo, strlen(foo));
+				if (col > 60 && matches[i+1] != NULL) {
+					xwrite(outputFd, "\n", 1);
+					col = 0;
+				}
+			}
+			/* Go to the next line */
+			xwrite(outputFd, "\n", 1);
+			/* Rewrite the prompt */
+			xwrite(outputFd, prompt, strlen(prompt));
+			/* Rewrite the command */
+			xwrite(outputFd, command, len);
+			/* Put the cursor back to where it used to be */
+			for (cursor=len; cursor > pos; cursor--)
+				xwrite(outputFd, "\b", 1);
+		}
+	}
+}
+#endif
+
+void get_previous_history(struct history **hp, char* command)
+{
+	free((*hp)->s);
+	(*hp)->s = strdup(command);
+	*hp = (*hp)->p;
+}
+
+void get_next_history(struct history **hp, char* command)
+{
+	free((*hp)->s);
+	(*hp)->s = strdup(command);
+	*hp = (*hp)->n;
+
+	cmdedit_redraw( NULL, hp->s, -2, -2); 
+}
+
+#if 0
+/* prompt : if !=NULL, print the prompt
+ * command: the command line to be displayed
+ * where  : where to display changes from.
+ *          -1 for no change, -2 for new line
+ * cursor : desired location for the cursor.
+ *          -1 for Beginning of line.
+ *          -2 for End of Line, 
+ */
+static void
+cmdedit_redraw(char* prompt, char* command, int where, int cursor)
+{
+	static char* last_command;
+	int cmdedit_width;
+
+	if (where == -2) {
+		/* Rewrite the prompt and clean up static variables */
+		xwrite(outputFd, "\n", 1);
+		if (prompt) {
+			strcpy(last_command, prompt);
+			xwrite(outputFd, prompt, strlen(prompt));
+		} else {
+			last_command[0] = '\0';
+			xwrite(outputFd, "# ", 2);
+		}
+		cmdedit_width = cmdedit_termw - cmdedit_strlen(prompt);
+	} else if (strcmp(command, last_command) != 0) {
+		strcpy(last_command, prompt);
+	}
+
+	/* erase old command from command line */
+	len = strlen(command)-strlen(last_command);
+	while (len>0)
+		input_backspace(command, outputFd, &cursor, &len);
+	input_home(outputFd, &cursor);
+
+	/* Rewrite the command */
+	xwrite(outputFd, command+where, len);
+
+	/* Put the where it is supposed to be */
+	for (cursor=len; cursor > where; cursor--)
+		xwrite(outputFd, "\b", 1);
+
+	/* write new command */
+	strcpy(command, hp->s);
+	len = strlen(hp->s);
+	xwrite(outputFd, command+where, len);
+	cursor = len;
+}
 #endif
 
 /*
@@ -245,12 +410,12 @@
  * Furthermore, the "vi" command editing keys are not implemented.
  *
  * TODO: implement TAB command completion. :)
- *
  */
-extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd,
-							  char command[BUFSIZ])
+extern void cmdedit_read_input(char* prompt, char command[BUFSIZ])
 {
 
+	int inputFd=fileno(stdin);
+	int outputFd=fileno(stdout);
 	int nr = 0;
 	int len = 0;
 	int j = 0;
@@ -262,297 +427,162 @@
 	struct history *hp = his_end;
 
 	memset(command, 0, sizeof(command));
-	parsenextc = command;
 	if (!reset_term) {
-		xioctl(inputFd, TCGETA, (void *) &old_term);
+		ioctl(inputFd, TCGETA, (void *) &old_term);
 		memcpy(&new_term, &old_term, sizeof(struct termio));
 
 		new_term.c_cc[VMIN] = 1;
 		new_term.c_cc[VTIME] = 0;
 		new_term.c_lflag &= ~ICANON;	/* unbuffered input */
 		new_term.c_lflag &= ~ECHO;
-		xioctl(inputFd, TCSETA, (void *) &new_term);
 		reset_term = 1;
+		ioctl(inputFd, TCSETA, (void *) &new_term);
 	} else {
-		xioctl(inputFd, TCSETA, (void *) &new_term);
+		ioctl(inputFd, TCSETA, (void *) &new_term);
 	}
 
-	memset(parsenextc, 0, BUFSIZ);
+	memset(command, 0, BUFSIZ);
 
 	while (1) {
 
 		if ((ret = read(inputFd, &c, 1)) < 1)
-			return ret;
-
-		fprintf(stderr, "\n\nkey=%d (%c)\n\n", c, c);
-		/* Go to the next line */
-		xwrite(outputFd, "\n", 1);
-		/* Rewrite the prompt */
-		xwrite(outputFd, prompt, strlen(prompt));
-		/* Rewrite the command */
-		xwrite(outputFd, parsenextc, len);
+			return;
 
 		switch (c) {
+		case '\n':
+		case '\r':
+			/* Enter */
+			*(command + len++ + 1) = c;
+			xwrite(outputFd, &c, 1);
+			break_out = 1;
+			break;
 		case 1:
 			/* Control-a -- Beginning of line */
 			input_home(outputFd, &cursor);
+		case 2:
+			/* Control-b -- Move back one character */
+			input_backward(outputFd, &cursor);
+			break;
+		case 4:
+			/* Control-d -- Delete one character, or exit 
+			 * if the len=0 and no chars to delete */
+			if (len == 0) {
+				xwrite(outputFd, "exit", 4);
+				clean_up_and_die(0);
+			} else {
+				input_delete(command, outputFd, cursor, &len);
+			}
+			break;
 		case 5:
 			/* Control-e -- End of line */
 			input_end(outputFd, &cursor, len);
 			break;
-		case 2:
-			/* Control-b -- Move back one character */
-			if (cursor > 0) {
-				xwrite(outputFd, "\033[D", 3);
-				cursor--;
-			}
-			break;
 		case 6:
 			/* Control-f -- Move forward one character */
-			if (cursor < len) {
-				xwrite(outputFd, "\033[C", 3);
-				cursor++;
-			}
+			input_forward(outputFd, &cursor, len);
 			break;
-		case 4:
-			/* Control-d -- Delete one character */
-			if (cursor != len) {
-				input_delete(outputFd, cursor);
-				len--;
-			} else if (len == 0) {
-				prepareToDie(0);
-				exit(0);
-			}
-			break;
-		case 14:
-			/* Control-n -- Get next command */
-			if (hp && hp->n && hp->n->s) {
-				free(hp->s);
-				hp->s = strdup(parsenextc);
-				hp = hp->n;
-				goto hop;
-			}
-			break;
-		case 16:
-			/* Control-p -- Get previous command */
-			if (hp && hp->p) {
-				free(hp->s);
-				hp->s = strdup(parsenextc);
-				hp = hp->p;
-				goto hop;
-			}
+		case '\b':
+		case DEL:
+			/* control-h and DEL */
+			input_backspace(command, outputFd, &cursor, &len);
 			break;
 		case '\t':
 #ifdef BB_FEATURE_SH_TAB_COMPLETION
-			{
-				/* Do TAB completion */
-				static int num_matches=0;
-				static char **matches = (char **) NULL;
-				int pos = cursor;
-				
-
-				if (lastWasTab == FALSE) {
-					char *tmp, *tmp1, *matchBuf;
-
-					/* For now, we will not bother with trying to distinguish
-					 * whether the cursor is in/at a command extression -- we
-					 * will always try all possable matches.  If you don't like
-					 * that then feel free to fix it.
-					 */
-					
-					/* Make a local copy of the string -- up 
-					 * to the position of the cursor */
-					matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
-					strncpy(matchBuf, parsenextc, cursor);
-					tmp=matchBuf;
-
-					/* skip past any command seperator tokens */
-					while (*tmp && (tmp1=strpbrk(tmp, ";|&{(`")) != NULL) {
-						tmp=++tmp1;
-						/* skip any leading white space */
-						while (*tmp && isspace(*tmp)) 
-							++tmp;
-					}
-
-					/* skip any leading white space */
-					while (*tmp && isspace(*tmp)) 
-						++tmp;
-
-					/* Free up any memory already allocated */
-					if (matches) {
-						free(matches);
-						matches = (char **) NULL;
-					}
-
-					/* If the word starts with `~' and there is no slash in the word, 
-					 * then try completing this word as a username. */
-
-					/* FIXME -- this check is broken! */
-					if (*tmp == '~' && !strchr(tmp, '/'))
-						matches = username_completion_matches(tmp, &num_matches);
-
-					/* Try to match any executable in our path and everything 
-					 * in the current working directory that matches.  */
-					if (!matches)
-						matches = find_path_executable_n_cwd_matches(tmp, &num_matches);
-
-					/* Don't leak memory */
-					free( matchBuf);
-
-					/* Did we find exactly one match? */
-					if (matches && num_matches==1) {
-						/* write out the matched command */
-						strncpy(parsenextc+pos, matches[0]+pos, strlen(matches[0])-pos);
-						len=strlen(parsenextc);
-						cursor=len;
-						xwrite(outputFd, matches[0]+pos, strlen(matches[0])-pos);
-						break;
-					}
-				} else {
-					/* Ok -- the last char was a TAB.  Since they
-					 * just hit TAB again, print a list of all the
-					 * available choices... */
-					if ( matches && num_matches>0 ) {
-						int i, col;
-						
-						/* Go to the next line */
-						xwrite(outputFd, "\n", 1);
-						/* Print the list of matches */
-						for (i=0,col=0; i<num_matches; i++) {
-							char foo[17];
-							sprintf(foo, "%-14s  ", matches[i]);
-							col += xwrite(outputFd, foo, strlen(foo));
-							if (col > 60 && matches[i+1] != NULL) {
-								xwrite(outputFd, "\n", 1);
-								col = 0;
-							}
-						}
-						/* Go to the next line */
-						xwrite(outputFd, "\n", 1);
-						/* Rewrite the prompt */
-						xwrite(outputFd, prompt, strlen(prompt));
-						/* Rewrite the command */
-						xwrite(outputFd, parsenextc, len);
-						/* Put the cursor back to where it used to be */
-						for (cursor=len; cursor > pos; cursor--)
-							xwrite(outputFd, "\b", 1);
-					}
-				}
-				break;
-			}
-#else
-			break;
+			input_tab(command, outputFd, &cursor, &len);
 #endif
-		case '\b':
-		case DEL:
-			/* Backspace */
-			input_backspace(outputFd, &cursor, &len);
 			break;
-		case '\n':
-			/* Enter */
-			*(parsenextc + len++ + 1) = c;
-			xwrite(outputFd, &c, 1);
-			break_out = 1;
+		case 14:
+			/* Control-n -- Get next command in history */
+			if (hp && hp->n && hp->n->s) {
+				get_next_history(&hp, command);
+				goto rewrite_line;
+			} else {
+				xwrite(outputFd, "\007", 1);
+			}
+			break;
+		case 16:
+			/* Control-p -- Get previous command from history */
+			if (hp && hp->p) {
+				get_previous_history(&hp, command);
+				goto rewrite_line;
+			} else {
+				xwrite(outputFd, "\007", 1);
+			}
 			break;
 		case ESC:{
 				/* escape sequence follows */
 				if ((ret = read(inputFd, &c, 1)) < 1)
-					return ret;
+					return;
 
 				if (c == '[') {	/* 91 */
 					if ((ret = read(inputFd, &c, 1)) < 1)
-						return ret;
+						return;
 
 					switch (c) {
 					case 'A':
-						/* Up Arrow -- Get previous command */
+						/* Up Arrow -- Get previous command from history */
 						if (hp && hp->p) {
-							free(hp->s);
-							hp->s = strdup(parsenextc);
-							hp = hp->p;
-							goto hop;
+							get_previous_history(&hp, command);
+							goto rewrite_line;
+						} else {
+							xwrite(outputFd, "\007", 1);
 						}
 						break;
 					case 'B':
-						/* Down Arrow -- Get next command */
+						/* Down Arrow -- Get next command in history */
 						if (hp && hp->n && hp->n->s) {
-							free(hp->s);
-							hp->s = strdup(parsenextc);
-							hp = hp->n;
-							goto hop;
+							get_next_history(&hp, command);
+							goto rewrite_line;
+						} else {
+							xwrite(outputFd, "\007", 1);
 						}
 						break;
 
-						/* This is where we rewrite the line 
-						 * using the selected history item */
-					  hop:
-						len = strlen(parsenextc);
-
-						/* return to begining of line */
-						for (; cursor > 0; cursor--)
-							xwrite(outputFd, "\b", 1);
-
-						/* erase old command */
-						for (j = 0; j < len; j++)
-							xwrite(outputFd, " ", 1);
-
-						/* return to begining of line */
-						for (j = len; j > 0; j--)
-							xwrite(outputFd, "\b", 1);
-
-						memset(parsenextc, 0, BUFSIZ);
-						len = strlen(parsenextc);
+						/* Rewrite the line with the selected history item */
+					  rewrite_line:
+						/* erase old command from command line */
+						len = strlen(command)-strlen(hp->s);
+						while (len>0)
+							input_backspace(command, outputFd, &cursor, &len);
+						input_home(outputFd, &cursor);
+						
 						/* write new command */
-						strcpy(parsenextc, hp->s);
+						strcpy(command, hp->s);
 						len = strlen(hp->s);
-						xwrite(outputFd, parsenextc, len);
+						xwrite(outputFd, command, len);
 						cursor = len;
 						break;
 					case 'C':
 						/* Right Arrow -- Move forward one character */
-						if (cursor < len) {
-							xwrite(outputFd, "\033[C", 3);
-							cursor++;
-						}
+						input_forward(outputFd, &cursor, len);
 						break;
 					case 'D':
 						/* Left Arrow -- Move back one character */
-						if (cursor > 0) {
-							xwrite(outputFd, "\033[D", 3);
-							cursor--;
-						}
+						input_backward(outputFd, &cursor);
 						break;
 					case '3':
 						/* Delete */
-						if (cursor != len) {
-							input_delete(outputFd, cursor);
-							len--;
-						}
+						input_delete(command, outputFd, cursor, &len);
 						break;
-
-					//case '5': case '6': /* pgup/pgdown */
-
-					case '7':
-						/* rxvt home */
 					case '1':
 						/* Home (Ctrl-A) */
 						input_home(outputFd, &cursor);
 						break;
-					case '8':
-						/* rxvt END */
 					case '4':
 						/* End (Ctrl-E) */
 						input_end(outputFd, &cursor, len);
 						break;
+					default:
+						xwrite(outputFd, "\007", 1);
 					}
 					if (c == '1' || c == '3' || c == '4')
 						if ((ret = read(inputFd, &c, 1)) < 1)
-							return ret;	/* read 126 (~) */
+							return;	/* read 126 (~) */
 				}
 				if (c == 'O') {
 					/* 79 */
 					if ((ret = read(inputFd, &c, 1)) < 1)
-						return ret;
+						return;
 					switch (c) {
 					case 'H':
 						/* Home (xterm) */
@@ -562,6 +592,8 @@
 						/* End (xterm) */
 						input_end(outputFd, &cursor, len);
 						break;
+					default:
+						xwrite(outputFd, "\007", 1);
 					}
 				}
 				c = 0;
@@ -570,8 +602,9 @@
 
 		default:				/* If it's regular input, do the normal thing */
 
-			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 */
 				break;
@@ -579,15 +612,15 @@
 			len++;
 
 			if (cursor == (len - 1)) {	/* Append if at the end of the line */
-				*(parsenextc + cursor) = c;
+				*(command + cursor) = c;
 			} else {			/* Insert otherwise */
-				memmove(parsenextc + cursor + 1, parsenextc + cursor,
+				memmove(command + cursor + 1, command + cursor,
 						len - cursor - 1);
 
-				*(parsenextc + cursor) = c;
+				*(command + cursor) = c;
 
 				for (j = cursor; j < len; j++)
-					xwrite(outputFd, parsenextc + j, 1);
+					xwrite(outputFd, command + j, 1);
 				for (; j > cursor; j--)
 					xwrite(outputFd, "\033[D", 3);
 			}
@@ -606,12 +639,12 @@
 	}
 
 	nr = len + 1;
-	xioctl(inputFd, TCSETA, (void *) &old_term);
+	ioctl(inputFd, TCSETA, (void *) &old_term);
 	reset_term = 0;
 
 
 	/* Handle command history log */
-	if (*(parsenextc)) {
+	if (*(command)) {
 
 		struct history *h = his_end;
 
@@ -621,7 +654,7 @@
 			h->n = malloc(sizeof(struct history));
 
 			h->p = NULL;
-			h->s = strdup(parsenextc);
+			h->s = strdup(command);
 			h->n->p = h;
 			h->n->n = NULL;
 			h->n->s = NULL;
@@ -634,7 +667,7 @@
 			h->n->p = h;
 			h->n->n = NULL;
 			h->n->s = NULL;
-			h->s = strdup(parsenextc);
+			h->s = strdup(command);
 			his_end = h->n;
 
 			/* After max history, remove the oldest command */
@@ -652,14 +685,14 @@
 		}
 	}
 
-	return nr;
+	return;
 }
 
 extern void cmdedit_init(void)
 {
 	atexit(cmdedit_reset_term);
-	signal(SIGINT, prepareToDie);
-	signal(SIGQUIT, prepareToDie);
-	signal(SIGTERM, prepareToDie);
+	signal(SIGINT, clean_up_and_die);
+	signal(SIGQUIT, clean_up_and_die);
+	signal(SIGTERM, clean_up_and_die);
 }
 #endif							/* BB_FEATURE_SH_COMMAND_EDITING */
diff --git a/shell/cmdedit.h b/shell/cmdedit.h
index 843a740..0e465e5 100644
--- a/shell/cmdedit.h
+++ b/shell/cmdedit.h
@@ -1,17 +1,35 @@
-/*
- * Termios command line History and Editting for NetBSD sh (ash)
- * Copyright (c) 1999
- *      Main code:            Adam Rogoyski <rogoyski@cs.utexas.edu> 
- *      Etc:                  Dave Cinege <dcinege@psychosis.com>
- *      Adjusted for busybox: Erik Andersen <andersee@debian.org>
- *
- * You may use this code as you wish, so long as the original author(s)
- * are attributed in any redistributions of the source code.
- * This code is 'as is' with no warranty.
- * This code may safely be consumed by a BSD or GPL license.
- *
+#ifndef GETLINE_H
+#define GETLINE_H
+
+/* unix systems can #define POSIX to use termios, otherwise 
+ * the bsd or sysv interface will be used 
  */
 
-extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd, char command[BUFSIZ]);
-extern void cmdedit_init(void);
+#ifdef __STDC__ 
+#include <stddef.h>
 
+typedef size_t (*cmdedit_strwidth_proc)(char *);
+
+void cmdedit_read_input(char* promptStr, char* command);		/* read a line of input */
+void cmdedit_setwidth(int);		/* specify width of screen */
+void cmdedit_histadd(char *);		/* adds entries to hist */
+void cmdedit_strwidth(cmdedit_strwidth_proc);	/* to bind cmdedit_strlen */
+
+extern int 	(*cmdedit_in_hook)(char *);
+extern int 	(*cmdedit_out_hook)(char *);
+extern int	(*cmdedit_tab_hook)(char *, int, int *);
+
+#else	/* not __STDC__ */
+
+void cmdedit_read_input(char* promptStr, char* command);
+void cmdedit_setwidth();
+void cmdedit_histadd();
+void cmdedit_strwidth();
+
+extern int 	(*cmdedit_in_hook)();
+extern int 	(*cmdedit_out_hook)();
+extern int	(*cmdedit_tab_hook)();
+
+#endif /* __STDC__ */
+
+#endif /* GETLINE_H */
diff --git a/shell/lash.c b/shell/lash.c
index f17097c..44ffe96 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -37,6 +37,9 @@
 #include <sys/ioctl.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#ifdef BB_FEATURE_SH_COMMAND_EDITING
+#include "cmdedit.h"
+#endif
 
 
 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@@ -132,6 +135,16 @@
 static char cwd[1024];
 static char *prompt = "# ";
 
+#ifdef BB_FEATURE_SH_COMMAND_EDITING
+void win_changed(int sig)
+{
+	struct winsize win = { 0, 0 };
+	ioctl(0, TIOCGWINSZ, &win);
+	if (win.ws_col > 0) {
+		cmdedit_setwidth( win.ws_col - 1);
+	}
+}
+#endif
 
 
 /* built-in 'cd <path>' handler */
@@ -398,7 +411,7 @@
 		fflush(stdout);
 		promptStr=(char*)malloc(sizeof(char)*(len+1));
 		sprintf(promptStr, "%s %s", cwd, prompt);
-		cmdedit_read_input(promptStr, fileno(stdin), fileno(stdout), command);
+		cmdedit_read_input(promptStr, command);
 		free( promptStr);
 		return 0;
 #else
@@ -696,7 +709,6 @@
 		strcpy(job->text, *commandPtr);
 	} else {
 		/* This leaves any trailing spaces, which is a bit sloppy */
-
 		count = returnCommand - *commandPtr;
 		job->text = malloc(count + 1);
 		strncpy(job->text, *commandPtr, count);
@@ -793,14 +805,12 @@
 	if (inBg) {
 		/* we don't wait for background jobs to return -- append it 
 		   to the list of backgrounded jobs and leave it alone */
-
 		printf("[%d] %d\n", job->jobId,
 			   newJob.progs[newJob.numProgs - 1].pid);
 	} else {
 		jobList->fg = job;
 
 		/* move the new process group into the foreground */
-
 		if (tcsetpgrp(0, newJob.pgrp))
 			perror("tcsetpgrp");
 	}
@@ -938,29 +948,24 @@
 	/* initialize the cwd */
 	getcwd(cwd, sizeof(cwd));
 
+#ifdef BB_FEATURE_SH_COMMAND_EDITING
+	signal(SIGWINCH, win_changed);
+	win_changed(0);
+#endif
 
 	//if (argv[0] && argv[0][0] == '-') {
 	//      shell_source("/etc/profile");
 	//}
 
 	if (argc < 2) {
-		fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER,
-				BB_BT);
-		fprintf(stdout,
-				"Enter 'help' for a list of built-in commands.\n\n");
+		fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT);
+		fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
 	} else {
 		input = fopen(argv[1], "r");
-		if (!input)
+		if (!input) {
 			fatalError("A: Couldn't open file '%s': %s\n", argv[1],
 					   strerror(errno));
-//              else
-//                      fatalError("Got it.\n");
-		//exit(shell_source(argv[1]));
-
-		/* Set terminal IO to canonical mode, and save old term settings. */
-#ifdef BB_FEATURE_SH_COMMAND_EDITING
-		cmdedit_init();
-#endif
+		}
 	}
 
 	return (busy_loop(input));