FreeCalypso > hg > freecalypso-reveng
comparison frbl/test/ttypassthru.c @ 323:cefa700d1b8f
frbl: beginning of frbl2test
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 05 Mar 2020 22:05:01 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 322:6e442ed0f64d | 323:cefa700d1b8f |
|---|---|
| 1 /* | |
| 2 * This module implements the pass-thru operation mode, in which | |
| 3 * the Unix host tty is cross-connected directly to the target | |
| 4 * running some code we have just loaded. | |
| 5 */ | |
| 6 | |
| 7 #include <sys/types.h> | |
| 8 #include <sys/ioctl.h> | |
| 9 #include <sys/errno.h> | |
| 10 #include <termios.h> | |
| 11 #include <stdio.h> | |
| 12 #include <stdlib.h> | |
| 13 #include <unistd.h> | |
| 14 #include <strings.h> | |
| 15 | |
| 16 extern int errno; | |
| 17 | |
| 18 extern int target_fd; | |
| 19 | |
| 20 static struct termios saved_termios, my_termios; | |
| 21 | |
| 22 static void | |
| 23 safe_output(buf, cc) | |
| 24 u_char *buf; | |
| 25 { | |
| 26 int i, c; | |
| 27 | |
| 28 for (i = 0; i < cc; i++) { | |
| 29 c = buf[i]; | |
| 30 if (c == '\r' || c == '\n' || c == '\t' || c == '\b') { | |
| 31 putchar(c); | |
| 32 continue; | |
| 33 } | |
| 34 if (c & 0x80) { | |
| 35 putchar('M'); | |
| 36 putchar('-'); | |
| 37 c &= 0x7F; | |
| 38 } | |
| 39 if (c < 0x20) { | |
| 40 putchar('^'); | |
| 41 putchar(c + '@'); | |
| 42 } else if (c == 0x7F) { | |
| 43 putchar('^'); | |
| 44 putchar('?'); | |
| 45 } else | |
| 46 putchar(c); | |
| 47 } | |
| 48 fflush(stdout); | |
| 49 } | |
| 50 | |
| 51 static void | |
| 52 loop() | |
| 53 { | |
| 54 char buf[BUFSIZ]; | |
| 55 fd_set fds, fds1; | |
| 56 register int i, cc, max; | |
| 57 | |
| 58 FD_ZERO(&fds); | |
| 59 FD_SET(0, &fds); | |
| 60 FD_SET(target_fd, &fds); | |
| 61 max = target_fd + 1; | |
| 62 for (;;) { | |
| 63 bcopy(&fds, &fds1, sizeof(fd_set)); | |
| 64 i = select(max, &fds1, NULL, NULL, NULL); | |
| 65 if (i < 0) { | |
| 66 if (errno == EINTR) | |
| 67 continue; | |
| 68 tcsetattr(0, TCSAFLUSH, &saved_termios); | |
| 69 perror("select"); | |
| 70 exit(1); | |
| 71 } | |
| 72 if (FD_ISSET(0, &fds1)) { | |
| 73 cc = read(0, buf, sizeof buf); | |
| 74 if (cc <= 0) | |
| 75 return; | |
| 76 if (cc == 1 && buf[0] == 0x1C) | |
| 77 return; | |
| 78 write(target_fd, buf, cc); | |
| 79 } | |
| 80 if (FD_ISSET(target_fd, &fds1)) { | |
| 81 cc = read(target_fd, buf, sizeof buf); | |
| 82 if (cc <= 0) { | |
| 83 tcsetattr(0, TCSAFLUSH, &saved_termios); | |
| 84 fprintf(stderr, "EOF/error on target tty\n"); | |
| 85 exit(1); | |
| 86 } | |
| 87 safe_output(buf, cc); | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 tty_passthru() | |
| 93 { | |
| 94 static int zero = 0; | |
| 95 | |
| 96 ioctl(target_fd, FIONBIO, &zero); | |
| 97 | |
| 98 tcgetattr(0, &saved_termios); | |
| 99 bcopy(&saved_termios, &my_termios, sizeof(struct termios)); | |
| 100 cfmakeraw(&my_termios); | |
| 101 my_termios.c_cc[VMIN] = 1; | |
| 102 my_termios.c_cc[VTIME] = 0; | |
| 103 tcsetattr(0, TCSAFLUSH, &my_termios); | |
| 104 | |
| 105 printf("Entering tty pass-thru; type ^\\ to exit\r\n\n"); | |
| 106 loop(); | |
| 107 tcsetattr(0, TCSAFLUSH, &saved_termios); | |
| 108 return 0; | |
| 109 } |
