Skip to content

Instantly share code, notes, and snippets.

@mraleph
Created February 19, 2020 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mraleph/b8f5afe4bf41f464164ffcd082ddbe46 to your computer and use it in GitHub Desktop.
Save mraleph/b8f5afe4bf41f464164ffcd082ddbe46 to your computer and use it in GitHub Desktop.
#include <stdio.h> // for fprintf()
#include <fcntl.h>
#include <unistd.h> // for close(), read()
#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
#include <string.h> // for strncmp
#include <errno.h>
const int kMaxEvents = 5;
const int kReadSize = 5;
int ParentMain(int pipe_in) {
struct epoll_event event, events[kMaxEvents];
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1) {
perror("epoll_create1() failed");
return 1;
}
event.events = EPOLLIN | EPOLLET;
event.data.fd = pipe_in;
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_in, &event)) {
perror("epoll_ctl failed");
close(epoll_fd);
return 1;
}
while (true) {
printf("\nPolling for input...\n");
int event_count = epoll_wait(epoll_fd, events, kMaxEvents, -1);
printf("%d ready events\n", event_count);
for(int i = 0; i < event_count; i++) {
printf("Reading file descriptor '%d' -- ", events[i].data.fd);
#if defined(DRAIN_UNTIL_EAGAIN)
const bool kShouldDrain = true;
#else
const bool kShouldDrain = false;
#endif
do {
char read_buffer[1000];
ssize_t bytes_read = read(events[i].data.fd, read_buffer, kReadSize);
if (bytes_read < 0) {
if (errno == EAGAIN) {
break;
}
perror("read() failed");
goto done;
}
printf("%zd bytes read.\n", bytes_read);
read_buffer[bytes_read] = '\0';
printf("Read %s\n", read_buffer);
} while(kShouldDrain);
}
}
done:
if(close(epoll_fd))
{
perror("close(epoll_fd) failed\n");
return 1;
}
return 0;
}
int ChildMain(int pipe_out) {
int i = 0;
while (true) {
char buffer[1000];
int bytes = snprintf(buffer, sizeof(buffer), "line %d\n", i++);
write(pipe_out, buffer, bytes);
}
return 0;
}
int main()
{
int fds[2];
if (pipe2(fds, O_NONBLOCK) < 0) {
perror("pipe() failed");
return 1;
}
const pid_t p = fork();
if (p < 0) {
perror("fork() failed");
return 1;
} else if (p > 0) {
return ParentMain(fds[0]);
} else {
return ChildMain(fds[1]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment