aboutsummaryrefslogtreecommitdiff
path: root/miscutils/microcom.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/microcom.c')
-rw-r--r--miscutils/microcom.c69
1 files changed, 30 insertions, 39 deletions
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index b9ed9e401..2857a1b1b 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -3,7 +3,7 @@
* bare bones 'talk to modem' program - similar to 'cu -l $device'
* inspired by mgetty's microcom
*
- * Copyright (C) 2007 by Vladimir Dronnikov <dronnikov@gmail.ru>
+ * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
*
* Licensed under GPLv2, see file LICENSE in this tarball for details.
*/
@@ -59,20 +59,9 @@ int microcom_main(int argc, char **argv)
int timeout = -1;
// fetch options
- char *opt_s;
- char *opt_d;
- char *opt_t;
unsigned opts;
- opt_complementary = "=1"; // exactly one arg should be there
- opts = getopt32(argv, "Xs:d:t:", &opt_s, &opt_d, &opt_t);
-
- // apply options
- if (opts & OPT_s)
- speed = xatoi_u(opt_s);
- if (opts & OPT_d)
- delay = xatoi_u(opt_d);
- if (opts & OPT_t)
- timeout = xatoi_u(opt_t);
+ opt_complementary = "=1:s+:d+:t+"; // exactly one arg should be there
+ opts = getopt32(argv, "Xs:d:t:", &speed, &delay, &timeout);
// argc -= optind;
argv += optind;
@@ -99,22 +88,16 @@ int microcom_main(int argc, char **argv)
}
// setup signals
- bb_signals_recursive(0
- + (1 << SIGHUP)
- + (1 << SIGINT)
- + (1 << SIGTERM)
- + (1 << SIGPIPE)
- , signal_handler);
+ bb_signals(0
+ + (1 << SIGHUP)
+ + (1 << SIGINT)
+ + (1 << SIGTERM)
+ + (1 << SIGPIPE)
+ , signal_handler);
// error exit code if we fail to open the device
signalled = 1;
- // open device
- sfd = open_or_warn(argv[0], O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (sfd < 0)
- goto done;
- fcntl(sfd, F_SETFL, O_RDWR | O_NOCTTY);
-
// put stdin to "raw mode" (if stdin is a TTY),
// handle one character at a time
if (isatty(STDIN_FILENO)) {
@@ -123,12 +106,15 @@ int microcom_main(int argc, char **argv)
goto done;
}
- // same thing for modem
+ // open device
+ sfd = open_or_warn(argv[0], O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (sfd < 0)
+ goto done;
+ fcntl(sfd, F_SETFL, 0);
+
+ // put device to "raw mode"
xget1(sfd, &tio, &tiosfd);
- // order device to hang up at exit
- tio.c_cflag |= (CREAD|HUPCL);
-// if (!istty)
-// tio.c_iflag |= (IGNCR);
+// tio.c_cflag |= (CREAD|HUPCL); // we just bail out on any device error
// set device speed
cfsetspeed(&tio, tty_value_to_baud(speed));
if (xset1(sfd, &tio, argv[0]))
@@ -143,21 +129,20 @@ int microcom_main(int argc, char **argv)
signalled = 0;
nfd = 2;
while (!signalled && safe_poll(pfd, nfd, timeout) > 0) {
- if (pfd[1].revents) {
+ if (nfd > 1 && pfd[1].revents) {
char c;
// read from stdin -> write to device
if (safe_read(STDIN_FILENO, &c, 1) < 1) {
// don't poll stdin anymore if we got EOF/error
- pfd[1].revents = 0;
nfd--;
- goto check_stdin;
+ goto skip_write;
}
// do we need special processing?
if (!(opts & OPT_X)) {
// ^@ sends Break
if (VINTR == c) {
tcsendbreak(sfd, 0);
- goto check_stdin;
+ goto skip_write;
}
// ^X exits
if (24 == c)
@@ -166,18 +151,24 @@ int microcom_main(int argc, char **argv)
write(sfd, &c, 1);
if (delay >= 0)
safe_poll(pfd, 1, delay);
+skip_write: ;
}
-check_stdin:
if (pfd[0].revents) {
+#define iobuf bb_common_bufsiz1
ssize_t len;
// read from device -> write to stdout
- len = safe_read(sfd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
+ len = safe_read(sfd, iobuf, sizeof(iobuf));
if (len > 0)
- full_write(STDOUT_FILENO, bb_common_bufsiz1, len);
- // else { EOF/error - what to do? }
+ full_write(STDOUT_FILENO, iobuf, len);
+ else {
+ // EOF/error -> bail out
+ signalled = SIGHUP;
+ break;
+ }
}
}
+ // restore device mode
tcsetattr(sfd, TCSAFLUSH, &tiosfd);
restore0_and_done: