1 diff -urN ash-0.4.0/Makefile ash-0.4.0-/Makefile
2 --- ash-0.4.0/Makefile Tue Apr 24 00:57:33 2001
3 +++ ash-0.4.0-/Makefile Tue Apr 24 00:59:53 2001
5 SHSRCS= alias.c cd.c echo.c error.c eval.c exec.c expand.c \
6 histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \
7 mystring.c options.c parser.c redir.c show.c trap.c output.c var.c \
8 - test.c setmode.c test.c
9 + test.c setmode.c test.c hetio.c
10 GENSRCS=builtins.c builtins.h init.c nodes.c arith.c arith.h lex.yy.c \
11 nodes.h syntax.c syntax.h token.h signames.c
12 SRCS= ${SHSRCS} ${GENSRCS}
14 mystring.o options.o output.o parser.o redir.o show.o \
15 trap.o var.o bltin/test.o signames.o \
16 builtins.o init.o nodes.o syntax.o arith.o lex.yy.o \
17 - setmode.o bltin/times.o
18 + setmode.o bltin/times.o hetio.o
22 CFLAGS=$(OPT_FLAGS) -DSHELL -I. -DNO_HISTORY -DBSD=1 -DSMALL -D_GNU_SOURCE \
23 - -DGLOB_BROKEN -D__COPYRIGHT\(x\)= -D__RCSID\(x\)= -D_DIAGASSERT\(x\)=
24 + -DGLOB_BROKEN -D__COPYRIGHT\(x\)= -D__RCSID\(x\)= -D_DIAGASSERT\(x\)= \
29 diff -urN ash-0.4.0/hetio.c ash-0.4.0-/hetio.c
30 --- ash-0.4.0/hetio.c Thu Jan 1 01:00:00 1970
31 +++ ash-0.4.0-/hetio.c Tue Apr 24 01:06:59 2001
34 + * Termios command line History and Editting for NetBSD sh (ash)
35 + * Copyright (c) 1999
36 + * Main code: Adam Rogoyski <rogoyski@cs.utexas.edu>
37 + * Etc: Dave Cinege <dcinege@psychosis.com>
39 + * You may use this code as you wish, so long as the original author(s)
40 + * are attributed in any redistributions of the source code.
41 + * This code is 'as is' with no warranty.
42 + * This code may safely be consumed by a BSD or GPL license.
44 + * v 0.5 19990328 Initial release
46 + * Future plans: Simple file and path name completion. (like BASH)
51 +Usage and Known bugs:
52 + Terminal key codes are not extensive, and more will probably
53 + need to be added. This version was created on Debian GNU/Linux 2.x.
54 + Delete, Backspace, Home, End, and the arrow keys were tested
55 + to work in an Xterm and console. Ctrl-A also works as Home.
56 + Ctrl-E also works as End. The binary size increase is <3K.
58 + Editting will not display correctly for lines greater then the
59 + terminal width. (more then one line.) However, history will.
68 +#include <sys/ioctl.h>
78 +#define MAX_HISTORY 15 /* Maximum length of the linked list for the command line history */
83 +static struct history *his_front = NULL; /* First element in command line list */
84 +static struct history *his_end = NULL; /* Last element in command line list */
85 +static struct termios old_term, new_term; /* Current termio and the previous termio before starting ash */
87 +static int history_counter = 0; /* Number of commands in history list */
88 +static int reset_term = 0; /* Set to true if the terminal needs to be reset upon exit */
89 +static int hetio_inter = 0;
99 +void input_delete (int);
100 +void input_home (int *);
101 +void input_end (int *, int);
102 +void input_backspace (int *, int *);
106 +void hetio_init(void)
112 +void hetio_reset_term(void)
115 + tcsetattr(1, TCSANOW, &old_term);
119 +void setIO(struct termios *new, struct termios *old) /* Set terminal IO to canonical mode, and save old term settings. */
122 + memcpy(new, old, sizeof(*new));
123 + new->c_cc[VMIN] = 1;
124 + new->c_cc[VTIME] = 0;
125 + new->c_lflag &= ~ICANON; /* unbuffered input */
126 + new->c_lflag &= ~ECHO;
127 + tcsetattr(0, TCSANOW, new);
130 +void input_home(int *cursor) /* Command line input routines */
132 + while (*cursor > 0) {
140 +void input_delete(int cursor)
144 + memmove(parsenextc + cursor, parsenextc + cursor + 1,
145 + BUFSIZ - cursor - 1);
146 + for (j = cursor; j < (BUFSIZ - 1); j++) {
147 + if (!*(parsenextc + j))
150 + out1c(*(parsenextc + j));
155 + while (j-- > cursor)
161 +void input_end(int *cursor, int len)
163 + while (*cursor < len) {
172 +input_backspace(int *cursor, int *len)
179 + memmove(parsenextc + *cursor, parsenextc + *cursor + 1,
180 + BUFSIZ - *cursor + 1);
182 + for (j = *cursor; j < (BUFSIZ - 1); j++) {
183 + if (!*(parsenextc + j))
186 + out1c(*(parsenextc + j));
191 + while (j-- > *cursor)
199 +int hetio_read_input(int fd)
203 + if (!hetio_inter) { /* Are we an interactive shell? */
212 + struct history *hp = his_end;
215 + setIO(&new_term, &old_term);
218 + tcsetattr(0, TCSANOW, &new_term);
221 + memset(parsenextc, 0, BUFSIZ);
224 + if ((ret = read(fd, &c, 1)) < 1)
228 + case 1: /* Control-A Beginning of line */
229 + input_home(&cursor);
231 + case 5: /* Control-E EOL */
232 + input_end(&cursor, len);
234 + case 4: /* Control-D */
235 +#ifndef CTRL_D_DELETE
238 + if (cursor != len) {
239 + input_delete(cursor);
244 + case '\b': /* Backspace */
246 + input_backspace(&cursor, &len);
248 + case '\n': /* Enter */
249 + *(parsenextc + len++ + 1) = c;
254 + case ESC: /* escape sequence follows */
255 + if ((ret = read(fd, &c, 1)) < 1)
258 + if (c == '[' || c == 'O' ) { /* 91 */
259 + if ((ret = read(fd, &c, 1)) < 1)
264 + if (hp && hp->p) { /* Up */
270 + if (hp && hp->n && hp->n->s) { /* Down */
277 + len = strlen(parsenextc);
279 + for (; cursor > 0; cursor--) /* return to begining of line */
282 + for (j = 0; j < len; j++) /* erase old command */
285 + for (j = len; j > 0; j--) /* return to begining of line */
288 + strcpy (parsenextc, hp->s); /* write new command */
289 + len = strlen (hp->s);
290 + out1str(parsenextc);
294 + case 'C': /* Right */
295 + if (cursor < len) {
301 + case 'D': /* Left */
308 + case '3': /* Delete */
309 + if (cursor != len) {
310 + input_delete(cursor);
314 + case 'H': /* Home (xterm) */
315 + case '1': /* Home (Ctrl-A) */
316 + input_home(&cursor);
318 + case 'F': /* End (xterm_ */
319 + case '4': /* End (Ctrl-E) */
320 + input_end(&cursor, len);
323 + if (c == '1' || c == '3' || c == '4')
324 + if ((ret = read(fd, &c, 1)) < 1)
325 + return ret; /* read 126 (~) */
331 + default: /* If it's regular input, do the normal thing */
333 + if (!isprint(c)) /* Skip non-printable characters */
336 + if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */
341 + if (cursor == (len - 1)) { /* Append if at the end of the line */
342 + *(parsenextc + cursor) = c;
343 + } else { /* Insert otherwise */
344 + memmove(parsenextc + cursor + 1, parsenextc + cursor,
347 + *(parsenextc + cursor) = c;
349 + for (j = cursor; j < len; j++)
350 + out1c(*(parsenextc + j));
351 + for (; j > cursor; j--)
361 + if (break_out) /* Enter is the command terminator, no more input. */
366 + tcsetattr(0, TCSANOW, &old_term);
369 + if (*(parsenextc)) { /* Handle command history log */
370 + struct history *h = his_end;
372 + if (!h) { /* No previous history */
373 + h = his_front = malloc(sizeof (struct history));
374 + h->n = malloc(sizeof (struct history));
376 + h->s = strdup(parsenextc);
383 + } else { /* Add a new history command */
385 + h->n = malloc(sizeof (struct history));
390 + h->s = strdup(parsenextc);
393 + if (history_counter >= MAX_HISTORY) { /* After max history, remove the last known command */
394 + struct history *p = his_front->n;
397 + free(his_front->s);
410 diff -urN ash-0.4.0/hetio.h ash-0.4.0-/hetio.h
411 --- ash-0.4.0/hetio.h Thu Jan 1 01:00:00 1970
412 +++ ash-0.4.0-/hetio.h Tue Apr 24 00:13:57 2001
415 + * Termios command line History and Editting for NetBSD sh (ash)
416 + * Copyright (c) 1999
417 + * Main code: Adam Rogoyski <rogoyski@cs.utexas.edu>
418 + * Etc: Dave Cinege <dcinege@psychosis.com>
420 + * You may use this code as you wish, so long as the original author(s)
421 + * are attributed in any redistributions of the source code.
422 + * This code is 'as is' with no warranty.
423 + * This code may safely be consumed by a BSD or GPL license.
425 + * v 0.5 19990328 Initial release
427 + * Future plans: Simple file and path name completion. (like BASH)
431 +void hetio_init(void);
432 +int hetio_read_input(int fd);
433 +void hetio_reset_term(void);
435 +extern int hetio_inter;
436 diff -urN ash-0.4.0/histedit.c ash-0.4.0-/histedit.c
437 --- ash-0.4.0/histedit.c Fri Jan 12 17:50:35 2001
438 +++ ash-0.4.0-/histedit.c Tue Apr 24 00:13:57 2001
442 #include "mystring.h"
443 -#include "myhistedit.h"
446 +#include "myhistedit.h"
448 #include "memalloc.h"
452 error("missing history argument");
457 optreset = 1; optind = 1; /* initialize getopt */
459 while (not_fcnumber(argv[optind]) &&
460 (ch = getopt(argc, argv, ":e:lnrs")) != -1)
462 diff -urN ash-0.4.0/input.c ash-0.4.0-/input.c
463 --- ash-0.4.0/input.c Tue May 23 12:03:19 2000
464 +++ ash-0.4.0-/input.c Tue Apr 24 00:13:57 2001
470 #include "myhistedit.h"
477 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
480 int init_editline = 0; /* editline library initialized? */
481 int whichprompt; /* 1 == PS1, 2 == PS2 */
484 EditLine *el; /* cookie for editline package */
487 STATIC void pushfile __P((void));
488 static int preadfd __P((void));
490 (void) strcpy(buf, rl_cp);
496 + nr = hetio_read_input(parsefile->fd);
499 nr = read(parsefile->fd, buf, BUFSIZ - 1);
501 diff -urN ash-0.4.0/main.c ash-0.4.0-/main.c
502 --- ash-0.4.0/main.c Tue Apr 24 00:57:33 2001
503 +++ ash-0.4.0-/main.c Tue Apr 24 00:13:57 2001
517 TRACE(("cmdloop(%d) called\n", top));
518 setstackmark(&smark);
526 Binary files ash-0.4.0/mksignames and ash-0.4.0-/mksignames differ
527 diff -urN ash-0.4.0/trap.c ash-0.4.0-/trap.c
528 --- ash-0.4.0/trap.c Tue Apr 24 00:57:33 2001
529 +++ ash-0.4.0-/trap.c Tue Apr 24 00:13:57 2001
533 #include "mystring.h"
541 * Sigmode records the current value of the signal handlers for the various
553 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
555 + hetio_reset_term();
557 if (setjmp(loc1.loc)) {