For every file descriptor, it calls that fd’s poll() method, which will add the caller to that fd’s wait queue, and return which events (readable, writeable, exception) currently apply to that fd.
1. How to add poll function to the kernel module code?
Include needed headers:
1 2
#include<linux/poll.h>
Declare waitqueue variable:
1
static(fortune_wait);
Add fortune_poll() function and add it (as .poll callback) to your file operations structure:
structscull_pipe { wait_queue_head_t inq, outq; char *buffer, *end; /* begin of buf, end of buf*/ int buffersize; /* used in pointer arithmetic*/ char *rp, *wp; /* where to read, where to write */ int nreaders, nwriters; /* number of openings for r/w */ structfasync_struct *async_queue;/* asynchronous readers */ structmutexmutex;/* mutual exclusion semaphore */ structcdevcdev;/* Char device structure */ };
/* * Do not touch the structure directly, use the access functions * poll_does_not_wait() and poll_requested_events() instead. */ typedefstructpoll_table_struct { poll_queue_proc _qproc; unsignedlong _key; } poll_table;
/* * structures and helpers for f_op->poll implementations */ typedefvoid(*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
The poll_table structure is just a wrapper around a function that builds the actual data structure. That structure, for poll and select, is a linked list of memory pages containing poll_table_entry structures.
/** * Insert a new element after the given list head. The new element does not * need to be initialised as empty list. * The list changes from: * head → some element → ... * to * head → new element → older element → ... * * Example: * struct foo *newfoo = malloc(...); * list_add(&newfoo->entry, &bar->list_of_foos); * * @param entry The new element to prepend to the list. * @param head The existing list. */ staticinlinevoid list_add(struct list_head *entry, struct list_head *head) { __list_add(entry, head, head->next); }