/* * term-enq * 2002-01-15 Fredrik Roubert * * Send ENQ (0x05) to the terminal, and print the returned string to stdout. * */ #include #include #include #include #include #include #include #if DEBUG # include # include # include # define PERROR(s) \ fprintf(stderr, __FILE__ ": line %i: %s(): %s\n", \ __LINE__, #s, strerror(errno)) #else # define PERROR(s) #endif int main(int argc, char *argv[]) { static const char tty[] = "/dev/tty", enq = 5; int fd; struct termios term_std, term_raw; fd_set rfds; struct timeval tv; unsigned char buf[255]; ssize_t size; if (-1 == (fd = open(tty, O_RDWR))) { PERROR(open); return EXIT_FAILURE; } if (0 != tcgetattr(fd, &term_std)) { PERROR(tcgetattr); return EXIT_FAILURE; } term_raw = term_std; term_raw.c_lflag &= ~(ECHO | ICANON); term_raw.c_cc[VTIME] = 5; term_raw.c_cc[VMIN] = 1; if (0 != tcsetattr(fd, TCSANOW, &term_raw)) { PERROR(tcsetattr); return EXIT_FAILURE; } if (1 != write(fd, &enq, 1)) { PERROR(write); goto exit_failure; } if (0 != usleep(250000)) { PERROR(usleep); goto exit_failure; } FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = 0; tv.tv_usec = 500000; switch (select(fd + 1, &rfds, NULL, NULL, &tv)) { case 0: goto exit_success; case 1: break; default: PERROR(select); goto exit_failure; } if (-1 == (size = read(fd, buf, sizeof buf))) { PERROR(read); goto exit_failure; } if (size > 0) { if (size >= sizeof buf) { goto exit_failure; } buf[size ++] = '\n'; if (size != write(STDOUT_FILENO, buf, size)) { PERROR(write); goto exit_failure; } } exit_success: if (0 != tcsetattr(fd, TCSANOW, &term_std)) { PERROR(tcsetattr); return EXIT_FAILURE; } return EXIT_SUCCESS; exit_failure: if (0 != tcsetattr(fd, TCSANOW, &term_std)) { PERROR(tcsetattr); } return EXIT_FAILURE; }