diff options
author | Roberto E. Vargas Caballero <k0ga@shike2.com> | 2015-04-13 19:03:53 +0200 |
---|---|---|
committer | Roberto E. Vargas Caballero <k0ga@shike2.com> | 2015-04-15 10:52:44 +0200 |
commit | 215bdb2da3eca77ba01b70503c527baaad67c359 (patch) | |
tree | d3d8ea65fb4496e9a26ebc55a898bc34ca37e5a8 /st.c | |
parent | 56abffb4b67f235d20de30f29ba027ab34c171e3 (diff) | |
download | st-215bdb2da3eca77ba01b70503c527baaad67c359.tar.gz st-215bdb2da3eca77ba01b70503c527baaad67c359.zip |
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 (limited to 'st.c')
-rw-r--r-- | st.c | 66 |
1 files changed, 54 insertions, 12 deletions
@@ -352,6 +352,7 @@ static void draw(void); | |||
352 | static void redraw(void); | 352 | static void redraw(void); |
353 | static void drawregion(int, int, int, int); | 353 | static void drawregion(int, int, int, int); |
354 | static void execsh(void); | 354 | static void execsh(void); |
355 | static void stty(void); | ||
355 | static void sigchld(int); | 356 | static void sigchld(int); |
356 | static void run(void); | 357 | static void run(void); |
357 | 358 | ||
@@ -508,6 +509,7 @@ static char *opt_title = NULL; | |||
508 | static char *opt_embed = NULL; | 509 | static char *opt_embed = NULL; |
509 | static char *opt_class = NULL; | 510 | static char *opt_class = NULL; |
510 | static char *opt_font = NULL; | 511 | static char *opt_font = NULL; |
512 | static char *opt_line = NULL; | ||
511 | static int oldbutton = 3; /* button event on startup: 3 = release */ | 513 | static int oldbutton = 3; /* button event on startup: 3 = release */ |
512 | 514 | ||
513 | static char *usedfont = NULL; | 515 | static char *usedfont = NULL; |
@@ -1253,11 +1255,55 @@ sigchld(int a) { | |||
1253 | exit(EXIT_SUCCESS); | 1255 | exit(EXIT_SUCCESS); |
1254 | } | 1256 | } |
1255 | 1257 | ||
1258 | |||
1259 | void | ||
1260 | stty(void) | ||
1261 | { | ||
1262 | char cmd[_POSIX_ARG_MAX], **p, *q, *s; | ||
1263 | size_t n, siz; | ||
1264 | |||
1265 | if((n = strlen(stty_args)) > sizeof(cmd)-1) | ||
1266 | die("incorrect stty parameters\n"); | ||
1267 | memcpy(cmd, stty_args, n); | ||
1268 | q = cmd + n; | ||
1269 | siz = sizeof(cmd) - n; | ||
1270 | for(p = opt_cmd; p && (s = *p); ++p) { | ||
1271 | if((n = strlen(s)) > siz-1) | ||
1272 | die("stty parameter length too long\n"); | ||
1273 | *q++ = ' '; | ||
1274 | q = memcpy(q, s, n); | ||
1275 | q += n; | ||
1276 | siz-= n + 1; | ||
1277 | } | ||
1278 | *q = '\0'; | ||
1279 | system(cmd); | ||
1280 | } | ||
1281 | |||
1256 | void | 1282 | void |
1257 | ttynew(void) { | 1283 | ttynew(void) { |
1258 | int m, s; | 1284 | int m, s; |
1259 | struct winsize w = {term.row, term.col, 0, 0}; | 1285 | struct winsize w = {term.row, term.col, 0, 0}; |
1260 | 1286 | ||
1287 | if(opt_io) { | ||
1288 | term.mode |= MODE_PRINT; | ||
1289 | iofd = (!strcmp(opt_io, "-")) ? | ||
1290 | STDOUT_FILENO : | ||
1291 | open(opt_io, O_WRONLY | O_CREAT, 0666); | ||
1292 | if(iofd < 0) { | ||
1293 | fprintf(stderr, "Error opening %s:%s\n", | ||
1294 | opt_io, strerror(errno)); | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | if (opt_line) { | ||
1299 | if((cmdfd = open(opt_line, O_RDWR)) < 0) | ||
1300 | die("open line failed: %s\n", strerror(errno)); | ||
1301 | close(STDIN_FILENO); | ||
1302 | dup(cmdfd); | ||
1303 | stty(); | ||
1304 | return; | ||
1305 | } | ||
1306 | |||
1261 | /* seems to work fine on linux, openbsd and freebsd */ | 1307 | /* seems to work fine on linux, openbsd and freebsd */ |
1262 | if(openpty(&m, &s, NULL, NULL, &w) < 0) | 1308 | if(openpty(&m, &s, NULL, NULL, &w) < 0) |
1263 | die("openpty failed: %s\n", strerror(errno)); | 1309 | die("openpty failed: %s\n", strerror(errno)); |
@@ -1267,6 +1313,7 @@ ttynew(void) { | |||
1267 | die("fork failed\n"); | 1313 | die("fork failed\n"); |
1268 | break; | 1314 | break; |
1269 | case 0: | 1315 | case 0: |
1316 | close(iofd); | ||
1270 | setsid(); /* create a new process group */ | 1317 | setsid(); /* create a new process group */ |
1271 | dup2(s, STDIN_FILENO); | 1318 | dup2(s, STDIN_FILENO); |
1272 | dup2(s, STDOUT_FILENO); | 1319 | dup2(s, STDOUT_FILENO); |
@@ -1281,16 +1328,6 @@ ttynew(void) { | |||
1281 | close(s); | 1328 | close(s); |
1282 | cmdfd = m; | 1329 | cmdfd = m; |
1283 | signal(SIGCHLD, sigchld); | 1330 | signal(SIGCHLD, sigchld); |
1284 | if(opt_io) { | ||
1285 | term.mode |= MODE_PRINT; | ||
1286 | iofd = (!strcmp(opt_io, "-")) ? | ||
1287 | STDOUT_FILENO : | ||
1288 | open(opt_io, O_WRONLY | O_CREAT, 0666); | ||
1289 | if(iofd < 0) { | ||
1290 | fprintf(stderr, "Error opening %s:%s\n", | ||
1291 | opt_io, strerror(errno)); | ||
1292 | } | ||
1293 | } | ||
1294 | break; | 1331 | break; |
1295 | } | 1332 | } |
1296 | } | 1333 | } |
@@ -4009,9 +4046,11 @@ run(void) { | |||
4009 | 4046 | ||
4010 | void | 4047 | void |
4011 | usage(void) { | 4048 | usage(void) { |
4012 | die("%s " VERSION " (c) 2010-2015 st engineers\n" \ | 4049 | die("%s " VERSION " (c) 2010-2015 st engineers\n" |
4013 | "usage: st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" | 4050 | "usage: st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" |
4014 | " [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n", | 4051 | " [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n" |
4052 | " st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n" | ||
4053 | " [-i] [-t title] [-w windowid] [-l line] [stty_args ...]\n", | ||
4015 | argv0); | 4054 | argv0); |
4016 | } | 4055 | } |
4017 | 4056 | ||
@@ -4047,6 +4086,9 @@ main(int argc, char *argv[]) { | |||
4047 | case 'o': | 4086 | case 'o': |
4048 | opt_io = EARGF(usage()); | 4087 | opt_io = EARGF(usage()); |
4049 | break; | 4088 | break; |
4089 | case 'l': | ||
4090 | opt_line = EARGF(usage()); | ||
4091 | break; | ||
4050 | case 't': | 4092 | case 't': |
4051 | opt_title = EARGF(usage()); | 4093 | opt_title = EARGF(usage()); |
4052 | break; | 4094 | break; |