| tmake echoing work. - plan9port - [fork] Plan 9 from user space | |
| git clone git://src.adamsgaard.dk/plan9port | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit a2705f207ff006c07c72081897ec4a6ca22ef269 | |
| parent aba09191af8012bc7d6a1b998ac937875f728d0c | |
| Author: rsc <devnull@localhost> | |
| Date: Fri, 16 Apr 2004 15:27:29 +0000 | |
| make echoing work. | |
| Diffstat: | |
| M src/cmd/9term/9term.c | 26 ++++++++++++++------------ | |
| D src/cmd/9term/9term.h | 4 ---- | |
| M src/cmd/9term/FreeBSD.c | 2 +- | |
| M src/cmd/9term/Linux.c | 64 +----------------------------… | |
| M src/cmd/9term/OpenBSD.c | 2 +- | |
| M src/cmd/9term/SunOS.c | 80 +++++++++--------------------… | |
| M src/cmd/9term/mkfile | 2 ++ | |
| M src/cmd/9term/rcstart.c | 23 +++++++++-------------- | |
| M src/cmd/9term/term.h | 2 +- | |
| 9 files changed, 51 insertions(+), 154 deletions(-) | |
| --- | |
| diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c | |
| t@@ -835,7 +835,7 @@ key(Rune r) | |
| return; | |
| } | |
| - rawon = israw(sfd); | |
| + rawon = !isecho(sfd); | |
| if(rawon && t.q0==t.nr){ | |
| addraw(&r, 1); | |
| consread(); | |
| t@@ -927,7 +927,7 @@ consready(void) | |
| if(holdon) | |
| return 0; | |
| - rawon = israw(sfd); | |
| + rawon = !isecho(sfd); | |
| if(rawon) | |
| return t.nraw != 0; | |
| t@@ -946,12 +946,11 @@ consread(void) | |
| { | |
| char buf[8000], *p; | |
| int c, width, n; | |
| - int echo; | |
| + int s; | |
| for(;;) { | |
| if(!consready()) | |
| return; | |
| - | |
| n = sizeof(buf); | |
| p = buf; | |
| c = 0; | |
| t@@ -965,19 +964,22 @@ consread(void) | |
| c = *p; | |
| p += width; | |
| n -= width; | |
| - rawon = israw(sfd); | |
| + rawon = !isecho(sfd); | |
| if(!rawon && (c == '\n' || c == '\004' || c == '\x7F')) | |
| break; | |
| } | |
| - /* take out control-d when not doing a zero length write */ | |
| n = p-buf; | |
| - if(0) fprint(2, "write buf\n"); | |
| - /* temporarily disable echo for buf. sensitive to race? Axel. … | |
| - // echo = setecho(sfd, 0); | |
| + | |
| + /* | |
| + * We've been echoing, so make sure the terminal isn't | |
| + * while we do the write. This screws up if someone | |
| + * else tries to turn on echo at the same time (we'll turn it | |
| + * off again after the write), but that's not too likely. | |
| + */ | |
| + s = setecho(sfd, 0); | |
| if(write(rcfd, buf, n) < 0) | |
| exits(0); | |
| - // setecho(sfd, echo); | |
| -/* mallocstats(); */ | |
| + setecho(sfd, s); | |
| } | |
| } | |
| t@@ -1258,7 +1260,7 @@ paste(Rune *r, int n, int advance) | |
| { | |
| Rune *rbuf; | |
| - rawon = israw(sfd); | |
| + rawon = !isecho(sfd); | |
| if(rawon && t.q0==t.nr){ | |
| addraw(r, n); | |
| return; | |
| diff --git a/src/cmd/9term/9term.h b/src/cmd/9term/9term.h | |
| t@@ -1,4 +0,0 @@ | |
| -extern int getpts(int[], char*); | |
| -extern int childpty(int[], char*); | |
| -extern void updatewinsize(int, int, int, int); | |
| -extern int rcfd[]; | |
| diff --git a/src/cmd/9term/FreeBSD.c b/src/cmd/9term/FreeBSD.c | |
| t@@ -1,10 +1,10 @@ | |
| #include <u.h> | |
| -#include "9term.h" | |
| #include <sys/types.h> | |
| #include <termios.h> | |
| #include <sys/termios.h> | |
| #include <libutil.h> | |
| #include <libc.h> | |
| +#include "term.h" | |
| int | |
| getpts(int fd[], char *slave) | |
| diff --git a/src/cmd/9term/Linux.c b/src/cmd/9term/Linux.c | |
| t@@ -1,63 +1 @@ | |
| -#include <u.h> | |
| -#include <termios.h> | |
| -#include <sys/termios.h> | |
| -#include <pty.h> | |
| -#include <libc.h> | |
| -#include "9term.h" | |
| - | |
| -int | |
| -getpts(int fd[], char *slave) | |
| -{ | |
| - openpty(&fd[1], &fd[0], slave, 0, 0); | |
| - return 0; | |
| -} | |
| - | |
| -int | |
| -childpty(int fd[], char *slave) | |
| -{ | |
| - int sfd; | |
| - | |
| - close(fd[1]); | |
| - setsid(); | |
| - sfd = open(slave, ORDWR); | |
| - if(sfd < 0) | |
| - sysfatal("open %s: %r\n", slave); | |
| - if(ioctl(sfd, TIOCSCTTY, 0) < 0) | |
| - fprint(2, "ioctl TIOCSCTTY: %r\n"); | |
| - return sfd; | |
| -} | |
| - | |
| -struct winsize ows; | |
| - | |
| -void | |
| -updatewinsize(int row, int col, int dx, int dy) | |
| -{ | |
| - struct winsize ws; | |
| - | |
| - ws.ws_row = row; | |
| - ws.ws_col = col; | |
| - ws.ws_xpixel = dx; | |
| - ws.ws_ypixel = dy; | |
| - if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) | |
| - if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0) | |
| - fprint(2, "ioctl: %r\n"); | |
| - ows = ws; | |
| -} | |
| - | |
| - | |
| -int | |
| -israw(int fd) | |
| -{ | |
| - return 0; | |
| -/* | |
| - if(tcgetattr(fd, &ttmode) < 0) | |
| - fprint(2, "tcgetattr: %r\n"); | |
| - return !(ttmode.c_lflag&(ICANON|ECHO)); | |
| -*/ | |
| -} | |
| - | |
| -int | |
| -setecho(int fd, int on) | |
| -{ | |
| - return 0; | |
| -} | |
| +#include "bsdpty.c" | |
| diff --git a/src/cmd/9term/OpenBSD.c b/src/cmd/9term/OpenBSD.c | |
| t@@ -1,11 +1,11 @@ | |
| #include <u.h> | |
| -#include "9term.h" | |
| #include <sys/types.h> | |
| #include <sys/ioctl.h> | |
| #include <termios.h> | |
| #include <sys/termios.h> | |
| #include <util.h> | |
| #include <libc.h> | |
| +#include "term.h" | |
| int | |
| getpts(int fd[], char *slave) | |
| diff --git a/src/cmd/9term/SunOS.c b/src/cmd/9term/SunOS.c | |
| t@@ -4,6 +4,8 @@ | |
| #include <libc.h> | |
| #include "term.h" | |
| +#define debug 0 | |
| + | |
| int | |
| getpts(int fd[], char *slave) | |
| { | |
| t@@ -55,72 +57,34 @@ updatewinsize(int row, int col, int dx, int dy) | |
| ows = ws; | |
| } | |
| -/* | |
| - * israw has been inspired by Matty Farrow's 9term. | |
| - * The code below is probably a gross simplification -- | |
| - * for the few cases tested it seems to be enough. | |
| - * However, for example, Matty's code also looks at ISIG, | |
| - * whereas, we do not (yet?). Axel. | |
| - * | |
| - *Note: I guess only the get/set terminal mode attribute | |
| - * code needs to be here; the logic around it could be | |
| - * elswhere (9term.c) - but if the code below is split, | |
| - * the question is what a nice interface would be. Axel. | |
| - */ | |
| - | |
| static struct termios ttmode; | |
| int | |
| israw(int fd) | |
| { | |
| - int e, c, i; | |
| - | |
| - tcgetattr(fd, &ttmode); | |
| - c = (ttmode.c_lflag & ICANON) ? 1 : 0; | |
| - e = (ttmode.c_lflag & ECHO) ? 1 : 0; | |
| - i = (ttmode.c_lflag & ISIG) ? 1 : 0; | |
| - | |
| - if(0) fprint(2, "israw: icanon=%d echo=%d isig=%d\n", c, e, i); | |
| - | |
| - return !c || !e ; | |
| + if(tcgetattr(fd, &ttmode) < 0) | |
| + fprint(2, "tcgetattr: %r\n"); | |
| + if(debug) fprint(2, "israw %c%c\n", | |
| + ttmode.c_lflag&ICANON ? 'c' : '-', | |
| + ttmode.c_lflag&ECHO ? 'e' : '-'); | |
| + return !(ttmode.c_lflag&(ICANON|ECHO)); | |
| } | |
| - | |
| int | |
| -setecho(int fd, int on) | |
| +setecho(int fd, int newe) | |
| { | |
| - int e, c, i; | |
| - int oldecho; | |
| - | |
| - tcgetattr(fd, &ttmode); | |
| - c = (ttmode.c_lflag & ICANON) ? 1 : 0; | |
| - e = (ttmode.c_lflag & ECHO) ? 1 : 0; | |
| - i = (ttmode.c_lflag & ISIG) ? 1 : 0; | |
| - | |
| - if(0) fprint(2, "setecho(%d) pre: icanon=%d echo=%d isig=%d\n", on, c,… | |
| - | |
| - oldecho = e; | |
| - | |
| - if (oldecho == on) | |
| - return oldecho; | |
| - | |
| - if (on) { | |
| - ttmode.c_lflag |= ECHO; | |
| - tcsetattr(fd, TCSANOW, &ttmode); | |
| - } else { | |
| - ttmode.c_lflag &= ~ECHO; | |
| - tcsetattr(fd, TCSANOW, &ttmode); | |
| - } | |
| - | |
| - if (0){ | |
| - tcgetattr(fd, &ttmode); | |
| - c = (ttmode.c_lflag & ICANON) ? 1 : 0; | |
| - e = (ttmode.c_lflag & ECHO) ? 1 : 0; | |
| - i = (ttmode.c_lflag & ISIG) ? 1 : 0; | |
| - | |
| - fprint(2, "setecho(%d) post: icanon=%d echo=%d isig=%d\n", on,… | |
| + int old; | |
| + | |
| + if(tcgetattr(fd, &ttmode) < 0) | |
| + fprint(2, "tcgetattr: %r\n"); | |
| + old = (ttmode.c_lflag&ECHO)==ECHO; | |
| + if(old != newe){ | |
| + if(newe) | |
| + ttmode.c_lflag |= ECHO; | |
| + else | |
| + ttmode.c_lflag &= ~ECHO; | |
| + if(tcsetattr(fd, TCSANOW, &ttmode) < 0) | |
| + fprint(2, "tcsetattr: %r\n"); | |
| } | |
| - | |
| - return oldecho; | |
| + return old; | |
| } | |
| - | |
| diff --git a/src/cmd/9term/mkfile b/src/cmd/9term/mkfile | |
| t@@ -13,3 +13,5 @@ SHORTLIB=complete frame draw plumb fs mux thread 9 | |
| LDFLAGS=-L$X11/lib -lX11 | |
| +Linux.$O: bsdpty.c | |
| + | |
| diff --git a/src/cmd/9term/rcstart.c b/src/cmd/9term/rcstart.c | |
| t@@ -6,17 +6,10 @@ | |
| #include <signal.h> | |
| #include "term.h" | |
| -/* | |
| - * Somehow we no longer automatically exit | |
| - * when the shell exits; hence the SIGCHLD stuff. | |
| - * Something that can be fixed? Axel. | |
| - */ | |
| -static int pid; | |
| - | |
| int | |
| rcstart(int argc, char **argv, int *pfd, int *tfd) | |
| { | |
| - int fd[2]; | |
| + int fd[2], i, pid; | |
| char *xargv[3]; | |
| char slave[256]; | |
| int sfd; | |
| t@@ -36,7 +29,6 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) | |
| fd[0] = fd[1] = -1; | |
| if(getpts(fd, slave) < 0) | |
| sysfatal("getpts: %r\n"); | |
| - | |
| switch(pid = fork()) { | |
| case 0: | |
| putenv("TERM", "9term"); | |
| t@@ -44,7 +36,9 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) | |
| dup(sfd, 0); | |
| dup(sfd, 1); | |
| dup(sfd, 2); | |
| - system("stty tabs -onlcr -echo erase '^h' intr '^?'"); | |
| + system("stty tabs -onlcr onocr icanon echo erase '^h' intr '^?… | |
| + for(i=3; i<100; i++) | |
| + close(i); | |
| execvp(argv[0], argv); | |
| fprint(2, "exec %s failed: %r\n", argv[0]); | |
| _exits("oops"); | |
| t@@ -54,10 +48,11 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) | |
| break; | |
| } | |
| *pfd = fd[1]; | |
| - if(tfd) | |
| - *tfd = fd[0]; | |
| - else | |
| - close(fd[0]); | |
| + close(fd[0]); | |
| + if(tfd){ | |
| + if((*tfd = open(slave, OREAD)) < 0) | |
| + sysfatal("parent open %s: %r", slave); | |
| + } | |
| return pid; | |
| } | |
| diff --git a/src/cmd/9term/term.h b/src/cmd/9term/term.h | |
| t@@ -3,5 +3,5 @@ extern int childpty(int[], char*); | |
| extern void updatewinsize(int, int, int, int); | |
| extern int rcfd; | |
| extern int rcstart(int, char*[], int*, int*); | |
| -extern int israw(int); | |
| +extern int isecho(int); | |
| extern int setecho(int, int); |