int main(int argc, char *argv[]) { int flags, j, cnt; struct termios origTermios; char ch; struct sigaction sa; Boolean done; /* Establish handler for "I/O possible" signal */ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigioHandler; if (sigaction(SIGIO, &sa, NULL) == -1) errExit("sigaction"); /* Set owner process that is to receive "I/O possible" signal */ if (fcntl(STDIN_FILENO, F_SETOWN, getpid()) == -1) errExit("fcntl(F_SETOWN)"); /* Enable "I/O possible" signaling and make I/O nonblocking for file descriptor */ flags = fcntl(STDIN_FILENO, F_GETFL); if (fcntl(STDIN_FILENO, F_SETFL, flags | O_ASYNC | O_NONBLOCK) == -1) errExit("fcntl(F_SETFL)"); /* Place terminal in cbreak mode */ if (ttySetCbreak(STDIN_FILENO, &origTermios) == -1) errExit("ttySetCbreak"); for (done = FALSE, cnt = 0; !done ; cnt++) { for (j = 0; j < 100000000; j++) continue; /* Slow main loop down a little */ if (gotSigio) { /* Is input available? */ gotSigio = 0; /* Read all available input until error (probably EAGAIN) or EOF (not actually possible in cbreak mode) or a hash (#) character is read */ while (read(STDIN_FILENO, &ch, 1) > 0 && !done) { printf("cnt=%d; read %c\n", cnt, ch); done = ch == '#'; } } } /* Restore original terminal settings */ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &origTermios) == -1) errExit("tcsetattr"); exit(EXIT_SUCCESS); }
int main() { int fd = STDIN_FILENO; int flags = fcntl(fd, F_GETFL); char ch; int done, cnt, j; struct sigaction sa; struct termios orig_termios; /* handler for i/o possible signal */ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigio_handler; if (sigaction(SIGIO, &sa, NULL) == -1) { return err_exit("sigaction"); } /* set owner, enable SIGIO signalling */ if (fcntl(fd, F_SETOWN, getpid()) == -1) { return err_exit("fcntl(F_SETOWN)"); } if (fcntl(fd, F_SETFL, flags | O_ASYNC | O_NONBLOCK) == -1) { return err_exit("fcntl(F_SETFL)"); } /* Do processing over the terminal until we ask it to exit */ /* Place terminal in cbreak mode */ if (ttySetCbreak(fd, &orig_termios) == -1) { return err_exit("ttySetCbreak"); } for (done = 0, cnt = 0; !done ; cnt++) { /* Slow main loop down a little */ for (j = 0; j < 100000000; j++) continue; if (gotSigio) { /* Is input available? */ /* Read all available input until error (probably EAGAIN) or EOF (not actually possible in cbreak mode) or a hash (#) character is read */ while (read(fd, &ch, 1) > 0 && !done) { printf("cnt=%d; read %c\n", cnt, ch); done = (ch == '#'); } gotSigio = 0; } } /* Restore original terminal settings */ if (tcsetattr(fd, TCSAFLUSH, &orig_termios) == -1) return err_exit("tcsetattr"); return 0; }
int main(int argc, char *argv[]) { char ch; struct sigaction sa, prev; ssize_t n; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (argc > 1) { /* Use cbreak mode */ if (ttySetCbreak(STDIN_FILENO, &userTermios) == -1) errExit("ttySetCbreak"); /* Terminal special characters can generate signals in cbreak mode. Catch them so that we can adjust the terminal mode. We establish handlers only if the signals are not being ignored. */ sa.sa_handler = handler; if (sigaction(SIGQUIT, NULL, &prev) == -1) errExit("sigaction"); if (prev.sa_handler != SIG_IGN) if (sigaction(SIGQUIT, &sa, NULL) == -1) errExit("sigaction"); if (sigaction(SIGINT, NULL, &prev) == -1) errExit("sigaction"); if (prev.sa_handler != SIG_IGN) if (sigaction(SIGINT, &sa, NULL) == -1) errExit("sigaction"); sa.sa_handler = tstpHandler; if (sigaction(SIGTSTP, NULL, &prev) == -1) errExit("sigaction"); if (prev.sa_handler != SIG_IGN) if (sigaction(SIGTSTP, &sa, NULL) == -1) errExit("sigaction"); } else { /* Use raw mode */ if (ttySetRaw(STDIN_FILENO, &userTermios) == -1) errExit("ttySetRaw"); } sa.sa_handler = handler; if (sigaction(SIGTERM, &sa, NULL) == -1) errExit("sigaction"); setbuf(stdout, NULL); /* Disable stdout buffering */ for (;;) { /* Read and echo stdin */ n = read(STDIN_FILENO, &ch, 1); if (n == -1) { errMsg("read"); break; } if (n == 0) /* Can occur after terminal disconnect */ break; if (isalpha((unsigned char) ch)) /* Letters --> lowercase */ putchar(tolower((unsigned char) ch)); else if (ch == '\n' || ch == '\r') putchar(ch); else if (iscntrl((unsigned char) ch)) printf("^%c", ch ^ 64); /* Echo Control-A as ^A, etc. */ else putchar('*'); /* All other chars as '*' */ if (ch == 'q') /* Quit loop */ break; } if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &userTermios) == -1) errExit("tcsetattr"); exit(EXIT_SUCCESS); }