From 42822ca572b43a83aaa1e1042e9546d366dca831 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 8 Dec 2020 23:39:50 -0500 Subject: Add modem -r flag to set baud rate Also fix it to continue reading output, rather than exiting as soon as the child exits... Except on macOS this still doesn't seem to work correctly for some reason. --- bin/man1/modem.1 | 14 +++++++++++--- bin/modem.c | 29 +++++++++++++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/bin/man1/modem.1 b/bin/man1/modem.1 index 522242b3..a4bbc3f1 100644 --- a/bin/man1/modem.1 +++ b/bin/man1/modem.1 @@ -1,4 +1,4 @@ -.Dd July 8, 2019 +.Dd December 8, 2020 .Dt MODEM 1 .Os . @@ -8,6 +8,7 @@ . .Sh SYNOPSIS .Nm +.Op Fl r Ar rate .Ar command ... . .Sh DESCRIPTION @@ -15,8 +16,15 @@ runs the .Ar command in a new PTY -with a fixed baud rate -of 19.2 kbps. +with a fixed baud rate. +. +.Pp +The arguments are as follows: +.Bl -tag -width Ds +.It Fl r Ar rate +Set the baud rate. +The default is 19200. +.El . .Sh BUGS Window size changes are not propagated diff --git a/bin/modem.c b/bin/modem.c index a003506f..2133ae08 100644 --- a/bin/modem.c +++ b/bin/modem.c @@ -34,8 +34,6 @@ typedef unsigned uint; typedef unsigned char byte; -static const uint BaudRate = 19200; - static struct termios saveTerm; static void restoreTerm(void) { tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm); @@ -44,7 +42,14 @@ static void restoreTerm(void) { int main(int argc, char *argv[]) { int error; - if (argc < 2) return EX_USAGE; + uint baudRate = 19200; + for (int opt; 0 < (opt = getopt(argc, argv, "r:"));) { + switch (opt) { + break; case 'r': baudRate = strtoul(optarg, NULL, 10); + break; default: return EX_USAGE; + } + } + if (argc - optind < 1) return EX_USAGE; error = tcgetattr(STDIN_FILENO, &saveTerm); if (error) err(EX_IOERR, "tcgetattr"); @@ -64,8 +69,8 @@ int main(int argc, char *argv[]) { if (pid < 0) err(EX_OSERR, "forkpty"); if (!pid) { - execvp(argv[1], &argv[1]); - err(EX_NOINPUT, "%s", argv[1]); + execvp(argv[optind], &argv[optind]); + err(EX_NOINPUT, "%s", argv[optind]); } byte c; @@ -73,7 +78,7 @@ int main(int argc, char *argv[]) { { .events = POLLIN, .fd = STDIN_FILENO }, { .events = POLLIN, .fd = pty }, }; - while (usleep(8 * 1000000 / BaudRate), 0 < poll(fds, 2, -1)) { + while (usleep(8 * 1000000 / baudRate), 0 < poll(fds, 2, -1)) { if (fds[0].revents) { ssize_t size = read(STDIN_FILENO, &c, 1); if (size < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO); @@ -84,14 +89,14 @@ int main(int argc, char *argv[]) { if (fds[1].revents) { ssize_t size = read(pty, &c, 1); if (size < 0) err(EX_IOERR, "read(%d)", pty); + if (!size) break; size = write(STDOUT_FILENO, &c, 1); if (size < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO); } - - int status; - pid_t dead = waitpid(pid, &status, WNOHANG); - if (dead < 0) err(EX_OSERR, "waitpid"); - if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE; } - err(EX_IOERR, "poll"); + + int status; + pid_t dead = waitpid(pid, &status, 0); + if (dead < 0) err(EX_OSERR, "waitpid"); + return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE; } -- cgit 1.4.1