/* Unix pty slave program License: GNU GPL version 2 Most of it taken from the GNU C library doc examples */ #include #include #include #include #include #include #include #include /* Use this variable to remember original terminal attributes. */ struct termios saved_attributes; static void reset_input_mode (void) { tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes); } static void set_input_mode (void) { struct termios tattr; /* Make sure stdin is a terminal. */ if (!isatty (STDIN_FILENO)) { fprintf (stderr, "Not a terminal.\n"); exit (EXIT_FAILURE); } /* Save the terminal attributes so we can restore them later. */ tcgetattr (STDIN_FILENO, &saved_attributes); atexit (reset_input_mode); /* Set the funny terminal modes. */ tcgetattr (STDIN_FILENO, &tattr); tattr.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON); tattr.c_lflag &= ~(ICANON|ECHO); tattr.c_cflag |= CLOCAL; tattr.c_cc[VMIN] = 1; tattr.c_cc[VTIME] = 0; tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); } int main (int argc, char *argv[]) { int term; if (argc < 2) { fprintf(stderr, "Usage: %s /dev/pts/number\n", argv[0]); return -1; } term = open(argv[1], O_RDWR); if (term < 0) { perror("open"); return -1; } if (! isatty(term)) { fprintf(stderr, "%s is not a valid terminal\n", argv[1]); return -1; } set_input_mode(); while (1) { fd_set cur_set; FD_ZERO(& cur_set); FD_SET(STDIN_FILENO, & cur_set); FD_SET(term, & cur_set); if (select(FD_SETSIZE, & cur_set, NULL, NULL, NULL) < 1) continue; if (FD_ISSET(term, & cur_set)) { char buf[1024]; int len = read(term, buf, sizeof(buf)); if (len >= 1) write(STDOUT_FILENO, buf, len); else { fprintf(stderr, "Master exitted\n"); break; } } if (FD_ISSET(STDIN_FILENO, & cur_set)) { char c; if (read(STDIN_FILENO, &c, 1) == 1) { if (c == 0x4) /* ctrl-D */ break; write(term, &c, 1); } else break; } } return 0; }