microcom.c 2.0 KB

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