Home | History | Annotate | Download | only in net
      1 /* microcom.c - Simple serial console.
      2  *
      3  * Copyright 2017 The Android Open Source Project.
      4 
      5 USE_MICROCOM(NEWTOY(microcom, "<1>1s:X", TOYFLAG_USR|TOYFLAG_BIN))
      6 
      7 config MICROCOM
      8   bool "microcom"
      9   default y
     10   help
     11     usage: microcom [-s SPEED] [-X] DEVICE
     12 
     13     Simple serial console.
     14 
     15     -s	Set baud rate to SPEED
     16     -X	Ignore ^@ (send break) and ^] (exit)
     17 */
     18 
     19 #define FOR_microcom
     20 #include "toys.h"
     21 
     22 GLOBALS(
     23   char *s;
     24 
     25   int fd;
     26   struct termios original_stdin_state, original_fd_state;
     27 )
     28 
     29 // TODO: tty_sigreset outputs ansi escape sequences, how to disable?
     30 static void restore_states(int i)
     31 {
     32   tcsetattr(0, TCSAFLUSH, &TT.original_stdin_state);
     33   tcsetattr(TT.fd, TCSAFLUSH, &TT.original_fd_state);
     34 }
     35 
     36 void microcom_main(void)
     37 {
     38   struct pollfd fds[2];
     39   int i, speed;
     40 
     41   if (!TT.s) speed = 115200;
     42   else speed = atoi(TT.s);
     43 
     44   // Open with O_NDELAY, but switch back to blocking for reads.
     45   TT.fd = xopen(*toys.optargs, O_RDWR | O_NOCTTY | O_NDELAY);
     46   if (-1==(i = fcntl(TT.fd, F_GETFL, 0)) || fcntl(TT.fd, F_SETFL, i&~O_NDELAY))
     47     perror_exit_raw(*toys.optargs);
     48 
     49   // Set both input and output to raw mode.
     50   xset_terminal(TT.fd, 1, speed, &TT.original_fd_state);
     51   set_terminal(0, 1, 0, &TT.original_stdin_state);
     52   // ...and arrange to restore things, however we may exit.
     53   sigatexit(restore_states);
     54 
     55   fds[0].fd = TT.fd;
     56   fds[0].events = POLLIN;
     57   fds[1].fd = 0;
     58   fds[1].events = POLLIN;
     59 
     60   while (poll(fds, 2, -1) > 0) {
     61     char buf[BUFSIZ];
     62 
     63     // Read from connection, write to stdout.
     64     if (fds[0].revents) {
     65       ssize_t n = read(TT.fd, buf, sizeof(buf));
     66       if (n > 0) xwrite(0, buf, n);
     67       else break;
     68     }
     69 
     70     // Read from stdin, write to connection.
     71     if (fds[1].revents) {
     72       if (read(0, buf, 1) != 1) break;
     73       if (!(toys.optflags & FLAG_X)) {
     74         if (!*buf) {
     75           tcsendbreak(TT.fd, 0);
     76           continue;
     77         } else if (*buf == (']'-'@')) break;
     78       }
     79       xwrite(TT.fd, buf, 1);
     80     }
     81   }
     82 }
     83