use stdio(3) - st - Simple Terminal
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a7f50ebb64892900e5b56e30c6edd83807a4040b
 (DIR) parent 07d1edcd76cf8ec3f6e72e79bbc1481da77e30f7
 (HTM) Author: Matthias-Christian Ott <ott@enolink.de>
       Date:   Mon, 25 Aug 2008 17:56:00 +0200
       
       use stdio(3)
       
       Diffstat:
         std.c                               |      95 ++++++++++++++++---------------
       
       1 file changed, 48 insertions(+), 47 deletions(-)
       ---
 (DIR) diff --git a/std.c b/std.c
       @@ -15,6 +15,7 @@
        #include <sys/wait.h>
        #include <ctype.h>
        #include <err.h>
       +#include <errno.h>
        #include <fcntl.h>
        #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
        #include <pty.h>
       @@ -36,15 +37,8 @@ typedef struct {
                int n;
        } RingBuffer;
        
       -ttypedef struct {
       -        unsigned char data[BUFSIZ];
       -        int i, n;
       -        int fd;
       -} ReadBuffer;
       -
        static void buffer(char c);
        static void cmd(const char *cmdstr, ...);
       -static int getch(ReadBuffer *buf);
        static void getpty(void);
        static void movea(int x, int y);
        static void mover(int x, int y);
       @@ -54,7 +48,6 @@ static void scroll(int l);
        static void shell(void);
        static void sigchld(int n);
        static char unbuffer(void);
       -static void ungetch(ReadBuffer *buf, int c);
        
        static int cols = 80, lines = 25;
        static int cx = 0, cy = 0;
       @@ -63,7 +56,7 @@ static int ptm, pts;
        static _Bool bold, digit, qmark;
        static pid_t pid;
        static RingBuffer buf;
       -static ReadBuffer cmdbuf, ptmbuf;
       +static FILE *fptm;
        
        void
        buffer(char c) {
       @@ -86,17 +79,6 @@ cmd(const char *cmdstr, ...) {
                va_end(ap);
        }
        
       -int
       -getch(ReadBuffer *buf) {
       -        if(buf->i++ >= buf->n) {
       -                buf->n = read(buf->fd, buf->data, BUFSIZ);
       -                if(buf->n == -1)
       -                        err(EXIT_FAILURE, "cannot read");
       -                buf->i = 0;
       -        }
       -        return buf->data[buf->i];
       -}
       -
        void
        movea(int x, int y) {
                x = MAX(x, cols);
       @@ -121,10 +103,10 @@ parseesc(void) {
                int arg[16];
        
                memset(arg, 0, LENGTH(arg));
       -        c = getch(&ptmbuf);
       +        c = getc(fptm);
                switch(c) {
                case '[':
       -                c = getch(&ptmbuf);
       +                c = getc(fptm);
                        for(j = 0; j < LENGTH(arg);) {
                                if(isdigit(c)) {
                                        digit = 1;
       @@ -146,7 +128,7 @@ parseesc(void) {
                                        }
                                        break;
                                }
       -                        c = getch(&ptmbuf);
       +                        c = getc(fptm);
                        }
                        switch(c) {
                        case '@':
       @@ -220,7 +202,7 @@ parseesc(void) {
                        break;
                default:
                        putchar('\033');
       -                ungetch(&ptmbuf, c);
       +                ungetc(c, fptm);
                }
        }
        
       @@ -308,13 +290,6 @@ unbuffer(void) {
                return c;
        }
        
       -void
       -ungetch(ReadBuffer *buf, int c) {
       -        if(buf->i + 1 >= buf->n)
       -                errx(EXIT_FAILURE, "buffer full");
       -        buf->data[buf->i++] = c;
       -}
       -
        int
        main(int argc, char *argv[]) {
                fd_set rfds;
       @@ -325,28 +300,31 @@ main(int argc, char *argv[]) {
                        errx(EXIT_FAILURE, "usage: std [-v]");
                getpty();
                shell();
       -        cmdbuf.fd = STDIN_FILENO;
       -        ptmbuf.fd = ptm;
                FD_ZERO(&rfds);
                FD_SET(STDIN_FILENO, &rfds);
                FD_SET(ptm, &rfds);
       +        if(!(fptm = fdopen(ptm, "r+")))
       +                err(EXIT_FAILURE, "cannot open pty");
       +        if(fcntl(ptm, F_SETFL, O_NONBLOCK) == -1)
       +                err(EXIT_FAILURE, "cannot set pty to non-blocking mode");
       +        if(fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
       +                err(EXIT_FAILURE, "cannot set stdin to non-blocking mode");
                for(;;) {
       -                if(select(ptm + 1, &rfds, NULL, NULL, NULL) == -1)
       +                if(select(MAX(ptm, STDIN_FILENO) + 1, &rfds, NULL, NULL, NULL) == -1)
                                err(EXIT_FAILURE, "cannot select");
       -                if(FD_ISSET(STDIN_FILENO, &rfds))
       -                        do {
       -                                c = getch(&cmdbuf);
       -                                switch(c) {
       -                                case ':':
       -                                        parsecmd();
       -                                        break;
       -                                default:
       +                if(FD_ISSET(ptm, &rfds)) {
       +                        for(;;) {
       +                                if((c = getc(fptm)) == EOF) {
       +                                        if(feof(fptm)) {
       +                                                FD_CLR(ptm, &rfds);
       +                                                fflush(fptm);
       +                                                break;
       +                                        }
       +                                        if(errno != EAGAIN)
       +                                                err(EXIT_FAILURE, "cannot read from pty");
       +                                        fflush(stdout);
                                                break;
                                        }
       -                        } while(cmdbuf.i < cmdbuf.n);
       -                if(FD_ISSET(ptm, &rfds)) {
       -                        do {
       -                                c = getch(&ptmbuf);
                                        switch(c) {
                                        case '\033':
                                                parseesc();
       @@ -354,9 +332,32 @@ main(int argc, char *argv[]) {
                                        default:
                                                putchar(c);
                                        }
       -                        } while(ptmbuf.i < ptmbuf.n);
       +                        }
                                fflush(stdout);
                        }
       +                if(FD_ISSET(STDIN_FILENO, &rfds)) {
       +                        for(;;) {
       +                                if((c = getchar()) == EOF) {
       +                                        if(feof(stdin)) {
       +                                                FD_CLR(STDIN_FILENO, &rfds);
       +                                                fflush(fptm);
       +                                                break;
       +                                        }
       +                                        if(errno != EAGAIN)
       +                                                err(EXIT_FAILURE, "cannot read from stdin");
       +                                        fflush(fptm);
       +                                        break;
       +                                }
       +                                switch(c) {
       +                                case ':':
       +                                        parsecmd();
       +                                        break;
       +                                default:
       +                                        putc(c, fptm);
       +                                }
       +                        }
       +                        fflush(fptm);
       +                }
                }
                return 0;
        }