The first thing to notice about pager.c is that it keeps per-client state. That is, for every file descriptor open to the driver, a structure is allocated that has information relating to that file descriptor. Previous driver examples were, for the most part, reactive--they received requests, and immediately generated responses. Since there was never more than one request outstanding, there was no need to keep a list of them. The pager application is the first one that must keep track of an arbitrary number of requests that might be outstanding at the same time. The first excerpt of pager.c, which appears in Program 11, shows the code which creates this per-client state. Lines 1-6 define a structure, pager_client, which keeps all the information we need about each client attached to the driver. The open callback for /dev/pager/notify, shown on lines 12-31, allocates memory for an instance of this structure and adds it to a linked list. (If the memory allocation fails, an error is returned to the client on line 18; this will prevent the file from opening.) Note on line 25 that we use the private_data field to store a pointer to the client state; this allows the structure to be retrieved when later callbacks on this file descriptor arrive. The memory is deallocated when the file is closed; we'll see that in a later section.
Another thing to notice about the open callback is the use of the last_page_seen variable. The driver gives a sequence number to every page it receives; last_page_seen stores the number of the most recent page seen by a client. When a new client arrives (i.e., it opens /dev/pager/notify), its last_page_seen state is set equal to the page that has most recently arrived; this forces a new client to wait for the next page, rather than immediately being notified of a page that has arrived in the past.