flash_eraseall: implement -N
[oweals/busybox.git] / miscutils / microcom.c
index 5219335a6eb0e92641543a6e0b161af4d6ebc064..5e29a1acdd483ba51e4382807c24685f8aa1b577 100644 (file)
@@ -5,17 +5,20 @@
  *
  * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
  *
- * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
-#include "libbb.h"
 
-/* All known arches use small ints for signals */
-static volatile smallint signalled;
+//usage:#define microcom_trivial_usage
+//usage:       "[-d DELAY] [-t TIMEOUT] [-s SPEED] [-X] TTY"
+//usage:#define microcom_full_usage "\n\n"
+//usage:       "Copy bytes for stdin to TTY and from TTY to stdout\n"
+//usage:     "\n       -d      Wait up to DELAY ms for TTY output before sending every"
+//usage:     "\n               next byte to it"
+//usage:     "\n       -t      Exit if both stdin and TTY are silent for TIMEOUT ms"
+//usage:     "\n       -s      Set serial line to SPEED"
+//usage:     "\n       -X      Disable special meaning of NUL and Ctrl-X from stdin"
 
-static void signal_handler(int signo)
-{
-       signalled = signo;
-}
+#include "libbb.h"
 
 // set raw tty mode
 static void xget1(int fd, struct termios *t, struct termios *oldt)
@@ -41,7 +44,7 @@ static int xset1(int fd, struct termios *tio, const char *device)
 }
 
 int microcom_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int microcom_main(int argc, char **argv)
+int microcom_main(int argc UNUSED_PARAM, char **argv)
 {
        int sfd;
        int nfd;
@@ -72,7 +75,7 @@ int microcom_main(int argc, char **argv)
        if (sfd < 0) {
                // device already locked -> bail out
                if (errno == EEXIST)
-                       bb_perror_msg_and_die("can't create %s", device_lock_file);
+                       bb_perror_msg_and_die("can't create '%s'", device_lock_file);
                // can't create lock -> don't care
                if (ENABLE_FEATURE_CLEAN_UP)
                        free(device_lock_file);
@@ -91,32 +94,31 @@ int microcom_main(int argc, char **argv)
                + (1 << SIGINT)
                + (1 << SIGTERM)
                + (1 << SIGPIPE)
-               , signal_handler);
+               , record_signo);
 
        // error exit code if we fail to open the device
-       signalled = 1;
-
-       // put stdin to "raw mode" (if stdin is a TTY),
-       // handle one character at a time
-       if (isatty(STDIN_FILENO)) {
-               xget1(STDIN_FILENO, &tio, &tio0);
-               if (xset1(STDIN_FILENO, &tio, "stdin"))
-                       goto done;
-       }
+       bb_got_signal = 1;
 
        // open device
        sfd = open_or_warn(argv[0], O_RDWR | O_NOCTTY | O_NONBLOCK);
        if (sfd < 0)
                goto done;
-       fcntl(sfd, F_SETFL, 0);
+       fcntl(sfd, F_SETFL, O_RDWR);
 
        // put device to "raw mode"
        xget1(sfd, &tio, &tiosfd);
-//     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]))
-               goto restore0_and_done;
+               goto done;
+
+       // put stdin to "raw mode" (if stdin is a TTY),
+       // handle one character at a time
+       if (isatty(STDIN_FILENO)) {
+               xget1(STDIN_FILENO, &tio, &tio0);
+               if (xset1(STDIN_FILENO, &tio, "stdin"))
+                       goto done;
+       }
 
        // main loop: check with poll(), then read/write bytes across
        pfd[0].fd = sfd;
@@ -124,9 +126,10 @@ int microcom_main(int argc, char **argv)
        pfd[1].fd = STDIN_FILENO;
        pfd[1].events = POLLIN;
 
-       signalled = 0;
+       bb_got_signal = 0;
        nfd = 2;
-       while (!signalled && safe_poll(pfd, nfd, timeout) > 0) {
+       // Not safe_poll: we want to exit on signal
+       while (!bb_got_signal && poll(pfd, nfd, timeout) > 0) {
                if (nfd > 1 && pfd[1].revents) {
                        char c;
                        // read from stdin -> write to device
@@ -160,7 +163,7 @@ skip_write: ;
                                full_write(STDOUT_FILENO, iobuf, len);
                        else {
                                // EOF/error -> bail out
-                               signalled = SIGHUP;
+                               bb_got_signal = SIGHUP;
                                break;
                        }
                }
@@ -169,7 +172,6 @@ skip_write: ;
        // restore device mode
        tcsetattr(sfd, TCSAFLUSH, &tiosfd);
 
-restore0_and_done:
        if (isatty(STDIN_FILENO))
                tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio0);
 
@@ -177,5 +179,5 @@ done:
        if (device_lock_file)
                unlink(device_lock_file);
 
-       return signalled;
+       return bb_got_signal;
 }