tmake echoing work. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a2705f207ff006c07c72081897ec4a6ca22ef269
 (DIR) parent aba09191af8012bc7d6a1b998ac937875f728d0c
 (HTM) 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(-)
       ---
 (DIR) 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;
 (DIR) 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[];
 (DIR) 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)
 (DIR) 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"
 (DIR) 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)
 (DIR) 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, 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;
        }
       -
 (DIR) 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
       +
 (DIR) 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;
        }
        
 (DIR) 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);