C poll() Function 🎯

beginner
7 min

C poll() Function 🎯

Welcome to a comprehensive guide on the poll() function in C programming! This function is a powerful tool for handling multiple events in a non-blocking manner, making it a valuable asset for developing efficient and responsive applications. Let's dive in and understand this fascinating concept together! 💡

What is the poll() function? 📝

The poll() function is part of the Advanced Linux Programming (ALP) library, which provides a more efficient alternative to the traditional Unix I/O functions like select() and pselect(). The primary advantage of poll() is that it allows for the handling of a large number of file descriptors more effectively, making it suitable for applications dealing with numerous network connections or I/O operations. 💡

The anatomy of a poll() object 📝

To work with the poll() function, we first need to create a struct pollfd object, which contains the necessary details about the file descriptor we want to monitor. Here's the structure definition:

c
struct pollfd { int fd; /* File descriptor */ short events; /* Events to watch for */ short revents; /* Returned events */ };

Let's break it down:

  1. fd: This is the file descriptor of the entity we're interested in, such as a socket, pipe, or terminal.
  2. events: This field contains a bitmask specifying the events we're interested in being notified about, such as readability, writability, or exceptions.
  3. revents: This field contains a bitmask that gets set to the actual events that occurred on the file descriptor while the call to poll() was blocking.

A practical example 📝

Let's put together a simple example to demonstrate the usage of the poll() function. We'll create a program that listens on a TCP socket and waits for incoming connections. As soon as a new connection is accepted, the program will start reading data from the client.

c
#include <stdio.h> #include <sys/socket.h> #include <poll.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; // Create a socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Set options on the socket if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } // Configure the address for the server address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // Bind the socket to the address if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // Listen for incoming connections if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // Create the polling array struct pollfd poll_fds[5]; poll_fds[0].fd = server_fd; poll_fds[0].events = POLLIN; // Accept incoming connections while (1) { int poll_result = poll(poll_fds, 1, -1); if (poll_result < 0) { perror("poll failed"); break; } if (poll_fds[0].revents & POLLIN) { // Accept a new connection if ((new_socket = accept(server_fd, (struct sockaddr *)NULL, (socklen_t *)NULL)) < 0) { perror("accept"); exit(EXIT_FAILURE); } // Add the new socket to the polling array poll_fds[1].fd = new_socket; poll_fds[1].events = POLLIN; } // Attempt to read data from the new connection if (poll_fds[1].revents & POLLIN) { read(poll_fds[1].fd, buffer, BUFFER_SIZE); printf("Received data: %s\n", buffer); } } return 0; }

This example creates a server that listens for incoming connections on port 8080. Once a new connection is established, it adds the new file descriptor to the polling array and starts monitoring it for read events. As soon as data arrives, it gets printed to the console.

Time to test your knowledge! 💡

Quick Quiz
Question 1 of 1

Which header file must be included to use the `poll()` function in C?

Quick Quiz
Question 1 of 1

What is the role of the `events` field in the `struct pollfd` object?