st

simple terminal
git clone git://git.suckless.org/st
Log | Files | Refs | README | LICENSE

commit 215bdb2da3eca77ba01b70503c527baaad67c359
parent 56abffb4b67f235d20de30f29ba027ab34c171e3
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:
Mconfig.def.h | 1+
Mst.1 | 37++++++++++++++++++++++++++++++++++++-
Mst.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 91 insertions(+), 13 deletions(-)

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"; 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. 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;