aboutsummaryrefslogtreecommitdiff
path: root/toys/net
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-11-18 15:18:05 -0600
committerRob Landley <rob@landley.net>2020-11-18 15:18:05 -0600
commitc251e32521229b7bd89a765481e2cd3b1ef02357 (patch)
treefad513b38735e8a486badeae8378f75baa96896f /toys/net
parent0ea04980e327efaf315a58408d926b674b55cb32 (diff)
downloadtoybox-c251e32521229b7bd89a765481e2cd3b1ef02357.tar.gz
Fix microcom to set serial device's terminal correctly.
Can't use the same set_terminal() logic as ptys because it not displaying data, it should just accurately copy it.
Diffstat (limited to 'toys/net')
-rw-r--r--toys/net/microcom.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/toys/net/microcom.c b/toys/net/microcom.c
index 62b020f2..963445c2 100644
--- a/toys/net/microcom.c
+++ b/toys/net/microcom.c
@@ -22,30 +22,35 @@ config MICROCOM
GLOBALS(
long s;
- int fd;
- struct termios original_stdin_state, original_fd_state;
+ int fd, stok;
+ struct termios old_stdin, old_fd;
)
// TODO: tty_sigreset outputs ansi escape sequences, how to disable?
static void restore_states(int i)
{
- tcsetattr(0, TCSAFLUSH, &TT.original_stdin_state);
- tcsetattr(TT.fd, TCSAFLUSH, &TT.original_fd_state);
+ if (TT.stok) tcsetattr(0, TCSAFLUSH, &TT.old_stdin);
+ tcsetattr(TT.fd, TCSAFLUSH, &TT.old_fd);
}
void microcom_main(void)
{
+ struct termios tio;
struct pollfd fds[2];
int i;
// Open with O_NDELAY, but switch back to blocking for reads.
TT.fd = xopen(*toys.optargs, O_RDWR | O_NOCTTY | O_NDELAY);
- if (-1==(i = fcntl(TT.fd, F_GETFL, 0)) || fcntl(TT.fd, F_SETFL, i&~O_NDELAY))
+ if (-1==(i = fcntl(TT.fd, F_GETFL, 0)) || fcntl(TT.fd, F_SETFL, i&~O_NDELAY)
+ || tcgetattr(TT.fd, &TT.old_fd))
perror_exit_raw(*toys.optargs);
// Set both input and output to raw mode.
- xset_terminal(TT.fd, 1, TT.s, &TT.original_fd_state);
- set_terminal(0, 1, 0, &TT.original_stdin_state);
+ memcpy(&tio, &TT.old_fd, sizeof(struct termios));
+ cfmakeraw(&tio);
+ xsetspeed(&tio, TT.s);
+ if (tcsetattr(TT.fd, TCSAFLUSH, &tio)) perror_exit("set speed");
+ if (!set_terminal(0, 1, 0, &TT.old_stdin)) TT.stok++;
// ...and arrange to restore things, however we may exit.
sigatexit(restore_states);