commit a2705f207ff006c07c72081897ec4a6ca22ef269 from: rsc date: Fri Apr 16 15:27:29 2004 UTC make echoing work. commit - aba09191af8012bc7d6a1b998ac937875f728d0c commit + a2705f207ff006c07c72081897ec4a6ca22ef269 blob - 852e7dac74804f88adf16a89cbc3c6c5f4264b50 blob + 2b2f55397632c5c44a19e4e0862d1efbf7fb9408 --- src/cmd/9term/9term.c +++ src/cmd/9term/9term.c @@ -835,7 +835,7 @@ key(Rune r) return; } - rawon = israw(sfd); + rawon = !isecho(sfd); if(rawon && t.q0==t.nr){ addraw(&r, 1); consread(); @@ -927,7 +927,7 @@ consready(void) if(holdon) return 0; - rawon = israw(sfd); + rawon = !isecho(sfd); if(rawon) return t.nraw != 0; @@ -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; @@ -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); } } @@ -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; blob - 57a8359e14a0285ea0f2162eb61a27a0f92175fe (mode 644) blob + /dev/null --- src/cmd/9term/9term.h +++ /dev/null @@ -1,4 +0,0 @@ -extern int getpts(int[], char*); -extern int childpty(int[], char*); -extern void updatewinsize(int, int, int, int); -extern int rcfd[]; blob - 75a97a4a334b2d375e8ab93b87a06958160f97ca blob + 6dba6dd455adca122db008fea04146939ba247c4 --- src/cmd/9term/FreeBSD.c +++ src/cmd/9term/FreeBSD.c @@ -1,10 +1,10 @@ #include -#include "9term.h" #include #include #include #include #include +#include "term.h" int getpts(int fd[], char *slave) blob - 823344c989e008f341ad58e8c54020e31c55946c blob + eec79c286b4360f3f20ac5f3478d7b949e150ddf --- src/cmd/9term/Linux.c +++ src/cmd/9term/Linux.c @@ -1,63 +1 @@ -#include -#include -#include -#include -#include -#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" blob - e4753de22cdb194eb87e2cbe810c7a025dda243c blob + ec8c5efb0e95a7b12f89c81003099e4f40403200 --- src/cmd/9term/OpenBSD.c +++ src/cmd/9term/OpenBSD.c @@ -1,11 +1,11 @@ #include -#include "9term.h" #include #include #include #include #include #include +#include "term.h" int getpts(int fd[], char *slave) blob - 252283443dd7af6c2691501c9c1ce08976d042cb blob + efc2a9796cc00494db14822d0952ed7f0a09c555 --- src/cmd/9term/SunOS.c +++ src/cmd/9term/SunOS.c @@ -4,6 +4,8 @@ #include #include "term.h" +#define debug 0 + int getpts(int fd[], char *slave) { @@ -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; + int old; - 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, e, i); - - 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(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"); } - - 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, c, e, i); - } - - return oldecho; + return old; } - blob - 81af3bcaa89015366bdb51702ad72cc81e90d589 blob + 8b06911da5d5c40f90a4bfbf2bc53fc19900add7 --- src/cmd/9term/mkfile +++ src/cmd/9term/mkfile @@ -13,3 +13,5 @@ SHORTLIB=complete frame draw plumb fs mux thread 9 LDFLAGS=-L$X11/lib -lX11 +Linux.$O: bsdpty.c + blob - 499c59186b6161a8ac2ddad8a64a7ffb28618624 blob + 4b3248309bba698fd49623c7fafb268780e23ca5 --- src/cmd/9term/rcstart.c +++ src/cmd/9term/rcstart.c @@ -6,17 +6,10 @@ #include #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; @@ -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"); @@ -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"); @@ -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; } blob - c35ff4a7514520f3d9e087938b8a447391f81941 blob + 4b5339ce72ff72dc62472e7054dbad36ec975b7a --- src/cmd/9term/term.h +++ src/cmd/9term/term.h @@ -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);