plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

commit a2705f207ff006c07c72081897ec4a6ca22ef269
parent aba09191af8012bc7d6a1b998ac937875f728d0c
Author: rsc <devnull@localhost>
Date:   Fri, 16 Apr 2004 15:27:29 +0000

make echoing work.

Diffstat:
Msrc/cmd/9term/9term.c | 26++++++++++++++------------
Dsrc/cmd/9term/9term.h | 4----
Msrc/cmd/9term/FreeBSD.c | 2+-
Msrc/cmd/9term/Linux.c | 64+---------------------------------------------------------------
Msrc/cmd/9term/OpenBSD.c | 2+-
Msrc/cmd/9term/SunOS.c | 80++++++++++++++++++++++---------------------------------------------------------
Msrc/cmd/9term/mkfile | 2++
Msrc/cmd/9term/rcstart.c | 23+++++++++--------------
Msrc/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 @@ -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; diff --git a/src/cmd/9term/9term.h b/src/cmd/9term/9term.h @@ -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 @@ -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 @@ -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 @@ -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 @@ -4,6 +4,8 @@ #include <libc.h> #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; - - 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 (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); + 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 @@ -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 @@ -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; @@ -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; } diff --git a/src/cmd/9term/term.h b/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);