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:

        $ stty raw </dev/ttyS0
        $ stty -iexten </dev/ttyS0
        $ stty 115200 </dev/ttyS0
        $ st -l /dev/ttyS0

Without this option was needed to launch another terminal emulator
over st (for example minicom, picocom, cu, ...).
---
 st.1 |  5 +++++
 st.c | 35 ++++++++++++++++++++++++-----------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/st.1 b/st.1
index a9fec15..97984b3 100644
--- a/st.1
+++ b/st.1
@@ -15,6 +15,8 @@ st \- simple terminal
 .IR file ]
 .RB [ \-t 
 .IR title ]
+.RB [ \-l
+.IR line ]
 .RB [ \-w 
 .IR windowid ]
 .RB [ \-v ]
@@ -58,6 +60,9 @@ 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.
+.TP
 .B \-v
 prints version information to stderr, then exits.
 .TP
diff --git a/st.c b/st.c
index 2a565b6..2a44983 100644
--- a/st.c
+++ b/st.c
@@ -508,6 +508,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,6 +1254,23 @@ 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));
+               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));
@@ -1268,6 +1286,7 @@ ttynew(void) {
                dup2(s, STDERR_FILENO);
                if(ioctl(s, TIOCSCTTY, NULL) < 0)
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
+               close(iofd);
                close(s);
                close(m);
                execsh();
@@ -1276,16 +1295,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;
        }
 }
@@ -4003,7 +4012,8 @@ void
 usage(void) {
        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 ...]\n", argv0);
+       "          [-i] [-l line] [-t title] [-w windowid] [-e command ...]\n",
+       argv0);
 }
 
 int
@@ -4042,6 +4052,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;
-- 
2.1.4


Reply via email to