This seems to work for me:
#include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> static void set_non_blocking(int fd) { int flags = fcntl(fd, F_GETFL, 0 ); flags |= O_NONBLOCK; flags = fcntl(fd, F_SETFL, flags); } int main(int argc, char ** argv) { int fd = fileno(stdin); char buf[10]; set_non_blocking(fd); while (read(fd, buf, sizeof buf) < 0) { perror("read"); sleep(1); } return 0; }
or you can use select :
int main(int argc, char ** argv) { int fd = fileno(stdin); struct timeval tv = {0,0}; fd_set fdset; int s; do { sleep(1); FD_ZERO(&fdset); FD_SET(fd, &fdset); } while ((s = select(fd+1, &fdset, NULL, NULL, &tv)) == 0); if (s < 0) { perror("select"); } return 0; }
The survey also works :-)
int main(int argc, char ** argv) { struct pollfd pfd; int s; pfd.fd = fileno(stdin); pfd.events = POLLRDNORM; while ((s = poll(&pfd, 1, 0)) == 0) { perror("polling"); sleep(1); } if (s < 0) { perror("poll"); } return 0; }
The last way is to install the terminal in raw mode. Note that this upsets the output to the terminal (at least on my OS-X) in that \ r becomes necessary after \ n. Also note that it must be undone at the end (the final call to tcsetattr ). This is the only one that does not need \ n (i.e. any keystroke)
#include <poll.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <termios.h> static void set_non_blocking(int fd) { int flags = fcntl(fd, F_GETFL, 0) | O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) { perror("fcntl"); exit(EXIT_FAILURE); } } int main(int argc, char ** argv) { struct termios params; struct termios params_orig; char buf[10]; int fd = fileno(stdin); if (tcgetattr(fd, ¶ms) < 0) { perror("tcgetattr"); exit(EXIT_FAILURE); } params_orig = params; cfmakeraw(¶ms); if (tcsetattr(fd, TCSANOW, ¶ms) < 0) { perror("tcsetattr"); exit(EXIT_FAILURE); } set_non_blocking(fd); while (read(fd, buf, sizeof buf) < 0) { perror("\rread"); sleep(1); } (void) tcsetattr(fd, TCSANOW, ¶ms_orig); return 0; }