Skip to content

Instantly share code, notes, and snippets.

@marcusmueller
Created November 8, 2025 12:23
Show Gist options
  • Select an option

  • Save marcusmueller/75ce2c00bf31bf152af877b833f2a472 to your computer and use it in GitHub Desktop.

Select an option

Save marcusmueller/75ce2c00bf31bf152af877b833f2a472 to your computer and use it in GitHub Desktop.
/* poll_input.c
Licensed under GNU General Public License v2 or later.
*/
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define errExit(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
int main(int argc, char *argv[]) {
int ready;
char buf[10];
nfds_t num_open_fds, nfds;
ssize_t s;
struct pollfd *pfds;
if (argc < 2) {
fprintf(stderr, "Usage: %s file...\n", argv[0]);
exit(EXIT_FAILURE);
}
num_open_fds = nfds = argc - 1;
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL)
errExit("malloc");
/* Open each file on command line, and add it to 'pfds' array. */
for (nfds_t j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
if (pfds[j].fd == -1)
errExit("open");
printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);
pfds[j].events = POLLIN;
}
/* Keep calling poll() as long as at least one file descriptor is
open. */
while (num_open_fds > 0) {
printf("About to poll()\n");
ready = poll(pfds, nfds, 10000);
if (ready == -1)
errExit("poll");
printf("Ready: %d\n", ready);
/* Deal with array returned by poll(). */
for (nfds_t j = 0; j < nfds; j++) {
if (pfds[j].revents != 0) {
printf(" fd=%d; events: %s%s%s\n", pfds[j].fd,
(pfds[j].revents & POLLIN) ? "POLLIN " : "",
(pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
(pfds[j].revents & POLLERR) ? "POLLERR " : "");
if (pfds[j].revents & POLLIN) {
s = read(pfds[j].fd, buf, sizeof(buf));
if (s == -1)
errExit("read");
printf(" read %zd bytes: %.*s\n", s, (int)s, buf);
} else { /* POLLERR | POLLHUP */
printf(" closing fd %d\n", pfds[j].fd);
if (close(pfds[j].fd) == -1)
errExit("close");
num_open_fds--;
}
}
}
}
printf("All file descriptors closed; bye\n");
exit(EXIT_SUCCESS);
}
#!/bin/sh
# compile modified example from man 2 poll
gcc -g -O2 -o pollexample pollexample.c
## set up fifo
rm fifo
mkfifo fifo
# open it for writing, so that opening it for reading in the example works
sleep 500 > fifo &
# start the example in the background in strace, so we can see the timestamps
strace -tt ./pollexample fifo &
# sleep one second so we're sure to be in the 10s polling timeout period
sleep 1
# STOP!
killall -STOP pollexample
# sleep a bit
sleep 2
# CONTINUE!
killall -CONT pollexample
# now let's wait for the timeout to have definitely occurred and kill the cat
sleep 10
rm fifo
killall pollexample
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment