/* con device */ #include #include #include #include #include #include #include struct termios save; void host(int fd) { int cc; char buf[128]; for (;;) { cc = read(fd, buf, sizeof buf); #ifdef HEX if (cc < 0) break; for (int i = 0; i < cc; ++i) { char hex[3]; sprintf(hex, "%02X", (unsigned char) buf[i]); write(1, hex, 2); } #else if (cc > 0) write(1, buf, cc); else if (cc < 0) break; #endif } } void hup(int signo) { write(1, "HUP\n", 4); tcsetattr(0, TCSADRAIN, &save); _exit(0); } void user(int fd) { char c, last = '\r'; signal(SIGHUP, hup); for (;;) while (read(0, &c, 1) > 0) { if (c == '~' && (last == '\n' || last == '\r' || last == 4)) { read(0, &c, 1); if (c == '.') return; } write(fd, &c, 1); last = c; } } int main(int argc, char *argv[]) { int fd; pid_t pid; struct termios t; if (argc != 2) exit(1); fd = open(argv[1], O_RDWR | O_NDELAY); if (fd < 0) exit(2); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY); tcgetattr(fd, &t); t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fd, TCSADRAIN, &t); tcgetattr(0, &t); save = t; t.c_iflag = 0; t.c_oflag = 0; t.c_lflag = 0; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(0, TCSADRAIN, &t); if ((pid = fork()) > 0) { user(fd); } else if (pid == 0) { host(fd); } else { perror("fork"); _exit(EXIT_FAILURE); } tcsetattr(0, TCSADRAIN, &save); kill(pid, SIGKILL); close(fd); _exit(EXIT_SUCCESS); }