Add tty line support - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 215bdb2da3eca77ba01b70503c527baaad67c359
 (DIR) parent 56abffb4b67f235d20de30f29ba027ab34c171e3
 (HTM) Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Mon, 13 Apr 2015 19:03:53 +0200
       
       Add tty line support
       
       Not always is desirable to create a pseudo terminal, and some times
       we want to open a terminal emulator over a tty line. With this new
       patch is possible to do someting like:
       
               $ st -l /dev/ttyS0 115200
       
       Without this option was needed to launch another terminal emulator
       over st (for example minicom, picocom, cu, ...).
       
       Diffstat:
         M config.def.h                        |       1 +
         M st.1                                |      37 ++++++++++++++++++++++++++++++-
         M st.c                                |      66 +++++++++++++++++++++++++------
       
       3 files changed, 91 insertions(+), 13 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       @@ -9,6 +9,7 @@ static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=fals
        static int borderpx = 2;
        static char shell[] = "/bin/sh";
        static char *utmp = NULL;
       +static char stty_args[] = "stty raw -echo -iexten echonl";
        
        /* identification sequence returned in DA and DECID */
        static char vtiden[] = "\033[?6c";
 (DIR) diff --git a/st.1 b/st.1
       @@ -15,11 +15,36 @@ st \- simple terminal
        .IR file ]
        .RB [ \-t 
        .IR title ]
       +.RB [ \-l
       +.IR line ]
        .RB [ \-w 
        .IR windowid ]
        .RB [ \-v ]
        .RB [ \-e
        .IR command ...]
       +.RI [ commands ...]
       +.PP
       +.B st
       +.RB [ \-a ]
       +.RB [ \-c
       +.IR class ]
       +.RB [ \-f
       +.IR font ]
       +.RB [ \-g
       +.IR geometry ]
       +.RB [ \-i ]
       +.RB [ \-o
       +.IR file ]
       +.RB [ \-t
       +.IR title ]
       +.RB [ \-l
       +.IR line ]
       +.RB [ \-w
       +.IR windowid ]
       +.RB [ \-v ]
       +.RB [ \-l
       +.IR line ]
       +.RI [ stty_args ...]
        .SH DESCRIPTION
        .B st
        is a simple terminal emulator.
       @@ -58,6 +83,11 @@ defines the window title (default 'st').
        embeds st within the window identified by 
        .I windowid
        .TP
       +.BI \-l " line"
       +use a tty line instead of a pseudo terminal.
       +When this flag is used
       +remaining arguments are used as flags for stty.
       +.TP
        .B \-v
        prints version information to stderr, then exits.
        .TP
       @@ -67,6 +97,9 @@ st executes
        instead of the shell.  If this is used it
        .B must be the last option
        on the command line, as in xterm / rxvt.
       +This option is only intended for compability,
       +and all the remaining arguments are used as a command
       +even without it.
        .SH SHORTCUTS
        .TP
        .B Ctrl-Print Screen
       @@ -110,7 +143,9 @@ See the LICENSE file for the authors.
        .SH LICENSE
        See the LICENSE file for the terms of redistribution.
        .SH SEE ALSO
       -.BR tabbed (1)
       +.BR tabbed (1),
       +.BR utmp (1),
       +.BR stty (1)
        .SH BUGS
        See the TODO file in the distribution.
        
 (DIR) diff --git a/st.c b/st.c
       @@ -352,6 +352,7 @@ static void draw(void);
        static void redraw(void);
        static void drawregion(int, int, int, int);
        static void execsh(void);
       +static void stty(void);
        static void sigchld(int);
        static void run(void);
        
       @@ -508,6 +509,7 @@ static char *opt_title = NULL;
        static char *opt_embed = NULL;
        static char *opt_class = NULL;
        static char *opt_font = NULL;
       +static char *opt_line = NULL;
        static int oldbutton = 3; /* button event on startup: 3 = release */
        
        static char *usedfont = NULL;
       @@ -1253,11 +1255,55 @@ sigchld(int a) {
                exit(EXIT_SUCCESS);
        }
        
       +
       +void
       +stty(void)
       +{
       +        char cmd[_POSIX_ARG_MAX], **p, *q, *s;
       +        size_t n, siz;
       +
       +        if((n = strlen(stty_args)) > sizeof(cmd)-1)
       +                die("incorrect stty parameters\n");
       +        memcpy(cmd, stty_args, n);
       +        q = cmd + n;
       +        siz = sizeof(cmd) - n;
       +        for(p = opt_cmd; p && (s = *p); ++p) {
       +                if((n = strlen(s)) > siz-1)
       +                        die("stty parameter length too long\n");
       +                *q++ = ' ';
       +                q = memcpy(q, s, n);
       +                q += n;
       +                siz-= n + 1;
       +        }
       +        *q = '\0';
       +        system(cmd);
       +}
       +
        void
        ttynew(void) {
                int m, s;
                struct winsize w = {term.row, term.col, 0, 0};
        
       +        if(opt_io) {
       +                term.mode |= MODE_PRINT;
       +                iofd = (!strcmp(opt_io, "-")) ?
       +                          STDOUT_FILENO :
       +                          open(opt_io, O_WRONLY | O_CREAT, 0666);
       +                if(iofd < 0) {
       +                        fprintf(stderr, "Error opening %s:%s\n",
       +                                opt_io, strerror(errno));
       +                }
       +        }
       +
       +        if (opt_line) {
       +                if((cmdfd = open(opt_line, O_RDWR)) < 0)
       +                        die("open line failed: %s\n", strerror(errno));
       +                close(STDIN_FILENO);
       +                dup(cmdfd);
       +                stty();
       +                return;
       +        }
       +
                /* seems to work fine on linux, openbsd and freebsd */
                if(openpty(&m, &s, NULL, NULL, &w) < 0)
                        die("openpty failed: %s\n", strerror(errno));
       @@ -1267,6 +1313,7 @@ ttynew(void) {
                        die("fork failed\n");
                        break;
                case 0:
       +                close(iofd);
                        setsid(); /* create a new process group */
                        dup2(s, STDIN_FILENO);
                        dup2(s, STDOUT_FILENO);
       @@ -1281,16 +1328,6 @@ ttynew(void) {
                        close(s);
                        cmdfd = m;
                        signal(SIGCHLD, sigchld);
       -                if(opt_io) {
       -                        term.mode |= MODE_PRINT;
       -                        iofd = (!strcmp(opt_io, "-")) ?
       -                                  STDOUT_FILENO :
       -                                  open(opt_io, O_WRONLY | O_CREAT, 0666);
       -                        if(iofd < 0) {
       -                                fprintf(stderr, "Error opening %s:%s\n",
       -                                        opt_io, strerror(errno));
       -                        }
       -                }
                        break;
                }
        }
       @@ -4009,9 +4046,11 @@ run(void) {
        
        void
        usage(void) {
       -        die("%s " VERSION " (c) 2010-2015 st engineers\n" \
       +        die("%s " VERSION " (c) 2010-2015 st engineers\n"
                "usage: st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n"
       -        "          [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n",
       +        "          [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n"
       +        "       st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n"
       +        "          [-i] [-t title] [-w windowid] [-l line] [stty_args ...]\n",
                argv0);
        }
        
       @@ -4047,6 +4086,9 @@ main(int argc, char *argv[]) {
                case 'o':
                        opt_io = EARGF(usage());
                        break;
       +        case 'l':
       +                opt_line = EARGF(usage());
       +                break;
                case 't':
                        opt_title = EARGF(usage());
                        break;