commit 4dcd9af228643d37bb63ab1642c5128b3b30f4bd from: rsc date: Thu Apr 15 02:04:30 2004 UTC 9term manages to turn off echo at the right times under SunOS ? commit - aeb54c0efed03187235820c73b7feef2260951cf commit + 4dcd9af228643d37bb63ab1642c5128b3b30f4bd blob - 2923deeae98637e02e5c0e5add7972ab0d6821a5 blob + 852e7dac74804f88adf16a89cbc3c6c5f4264b50 --- src/cmd/9term/9term.c +++ src/cmd/9term/9term.c @@ -124,6 +124,7 @@ int scrolling; /* window scrolls */ int clickmsec; /* time of last click */ uint clickq0; /* point of last click */ int rcfd; +int sfd; /* slave fd, to get/set terminal mode */ int rcpid; int maxtab; int use9wm; @@ -223,7 +224,7 @@ threadmain(int argc, char *argv[]) mc = initmouse(nil, screen); kc = initkeyboard(nil); - rcpid = rcstart(argc, argv, &rcfd); + rcpid = rcstart(argc, argv, &rcfd, &sfd); hoststart(); plumbstart(); @@ -269,6 +270,10 @@ hangupnote(void *a, char *msg) if(strcmp(msg, "hangup") == 0 && rcpid != 0){ postnote(PNGROUP, rcpid, "hangup"); noted(NDFLT); + } + if(strstr(msg, "child")){ + /* bug: do better */ + exits(0); } noted(NDFLT); } @@ -284,6 +289,8 @@ hostproc(void *arg) i = 0; for(;;){ /* Let typing have a go -- maybe there's a rubout waiting. */ + yield(); + i = 1-i; /* toggle */ n = threadread(rcfd, rcbuf[i].data, sizeof rcbuf[i].data); if(n <= 0){ @@ -828,6 +835,7 @@ key(Rune r) return; } + rawon = israw(sfd); if(rawon && t.q0==t.nr){ addraw(&r, 1); consread(); @@ -837,6 +845,7 @@ key(Rune r) if(r==ESC || (holdon && r==0x7F)){ /* toggle hold */ holdon = !holdon; drawhold(holdon); + // replaceintegerproperty("_9WM_HOLD_MODE", 1, 32, holdon); if(!holdon) consread(); if(r==ESC) @@ -918,6 +927,7 @@ consready(void) if(holdon) return 0; + rawon = israw(sfd); if(rawon) return t.nraw != 0; @@ -936,6 +946,7 @@ consread(void) { char buf[8000], *p; int c, width, n; + int echo; for(;;) { if(!consready()) @@ -954,13 +965,18 @@ consread(void) c = *p; p += width; n -= width; + rawon = israw(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); if(write(rcfd, buf, n) < 0) exits(0); + // setecho(sfd, echo); /* mallocstats(); */ } } @@ -1242,6 +1258,7 @@ paste(Rune *r, int n, int advance) { Rune *rbuf; + rawon = israw(sfd); if(rawon && t.q0==t.nr){ addraw(r, n); return; blob - 38212d6bf708e9c158a6bffdf63a414580096dfa blob + 8fff13f8a3d0e4f655b2e1388ddd4050b6ab44e0 --- src/cmd/9term/Darwin.c +++ src/cmd/9term/Darwin.c @@ -133,3 +133,15 @@ myopenpty(int fd[], char *name) } +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + blob - 89f7c7b60b4f8efb96fb2cc05ba796eb4c424f83 blob + 75a97a4a334b2d375e8ab93b87a06958160f97ca --- src/cmd/9term/FreeBSD.c +++ src/cmd/9term/FreeBSD.c @@ -44,3 +44,15 @@ updatewinsize(int row, int col, int dx, int dy) ows = ws; } +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + blob - 872417e6c501b8c3f1f8d0bcaba529e0f6110c67 blob + 823344c989e008f341ad58e8c54020e31c55946c --- src/cmd/9term/Linux.c +++ src/cmd/9term/Linux.c @@ -44,3 +44,20 @@ updatewinsize(int row, int col, int dx, int dy) 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; +} blob - 7f18bb43adad7581fbed7cc1a6d1e7b5c1d7988f blob + e4753de22cdb194eb87e2cbe810c7a025dda243c --- src/cmd/9term/OpenBSD.c +++ src/cmd/9term/OpenBSD.c @@ -44,3 +44,16 @@ updatewinsize(int row, int col, int dx, int dy) fprint(2, "ioctl: %r\n"); ows = ws; } + +int +israw(int fd) +{ + return 0; +} + +int +setecho(int fd, int on) +{ + return 0; +} + blob - d9104ed7da820fdcb17ec63b518e6dd7ec15abff blob + 252283443dd7af6c2691501c9c1ce08976d042cb --- src/cmd/9term/SunOS.c +++ src/cmd/9term/SunOS.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "term.h" @@ -11,8 +11,17 @@ getpts(int fd[], char *slave) if ((grantpt(fd[1]) < 0) || (unlockpt(fd[1]) < 0)) return -1; fchmod(fd[1], 0622); + strcpy(slave, ptsname(fd[1])); - fd[0] = open(slave, OREAD); + + fd[0] = open(slave, ORDWR); + if(fd[0] < 0) + sysfatal("open %s: %r\n", slave); + + /* set up the right streams modules for a tty */ + ioctl(fd[0], I_PUSH, "ptem"); /* push ptem */ + ioctl(fd[0], I_PUSH, "ldterm"); /* push ldterm */ + return 0; } @@ -42,7 +51,76 @@ updatewinsize(int row, int col, int dx, int dy) ws.ws_ypixel = dy; if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) if(ioctl(rcfd, TIOCSWINSZ, &ws) < 0) - fprint(2, "ioctl: %r\n"); + fprint(2, "ioctl TIOCSWINSZ: %r\n"); 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 ; +} + + +int +setecho(int fd, int on) +{ + 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); + } + + return oldecho; +} + blob - ec168e99389d6e4101b09761307f43a84bf558b0 blob + 499c59186b6161a8ac2ddad8a64a7ffb28618624 --- src/cmd/9term/rcstart.c +++ src/cmd/9term/rcstart.c @@ -1,11 +1,21 @@ #include #include +#if 0 +#include +#endif +#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) +rcstart(int argc, char **argv, int *pfd, int *tfd) { - int pid; int fd[2]; char *xargv[3]; char slave[256]; @@ -27,7 +37,6 @@ rcstart(int argc, char **argv, int *pfd) if(getpts(fd, slave) < 0) sysfatal("getpts: %r\n"); - switch(pid = fork()) { case 0: putenv("TERM", "9term"); @@ -44,8 +53,11 @@ rcstart(int argc, char **argv, int *pfd) sysfatal("proc failed: %r"); break; } - close(fd[0]); *pfd = fd[1]; + if(tfd) + *tfd = fd[0]; + else + close(fd[0]); return pid; } blob - a608b7edf837e9ed63229c934b86ee54be73ce8d blob + c35ff4a7514520f3d9e087938b8a447391f81941 --- src/cmd/9term/term.h +++ src/cmd/9term/term.h @@ -2,4 +2,6 @@ extern int getpts(int[], char*); extern int childpty(int[], char*); extern void updatewinsize(int, int, int, int); extern int rcfd; -extern int rcstart(int, char*[], int*); +extern int rcstart(int, char*[], int*, int*); +extern int israw(int); +extern int setecho(int, int); blob - d5dbef2ca298c439e46cf7e39fe3b903fcbc18a8 blob + 0e1fd8a68df345c75d0d5ac6dfade4923a59729a --- src/cmd/9term/win.c +++ src/cmd/9term/win.c @@ -161,7 +161,7 @@ threadmain(int argc, char **argv) cwait = threadwaitchan(); threadcreate(waitthread, nil, STACK); - pid = rcstart(argc, argv, &rcfd); + pid = rcstart(argc, argv, &rcfd, nil); if(pid == -1) sysfatal("exec failed");