| 
 |  | 
#include <sys/select.h>void selsuccess(void);
void selfailure(void);
void selwakeup(struct proc
proc_ptr, long flags);
The select(S) system call code sends a unique I/O control command to the driver to ask whether or not a condition is satisfied for reading, writing, or exceptional circumstances.
selfailure( ) indicates that the condition selected by the user is not true
selsuccess( ) indicates that the condition selected by the user is true
selwakeup( ) indicates that the condition selected by the user and that was not initially satisfied is now true.
Drivers supporting select(S) must include global declarations like the following:
   #include <sys/select.h>
   extern int selwait;
   struct xx_selstr
   {
       struct proc *read;
       struct proc *write;
       struct proc *except;
       char flags;
   }
   xxselstr[NUM_MINOR_DEVS];
       /*
        * This routine from driver xx handles a select for read
        * request. Note all requests come from the select system
        * call individually.
        */
   
   xxioctl(dev_t dev, int cmd, int arg, int mode);
   {
       ...
       if (cmd == IOC_SELECT)
           {
           switch (mode)
               {
               case SELREAD:   xx_selread(dev);
               break;
   
               /*
                * likewise for SELWRITE and SELEXCEPT
                */
               }
               return;
           }
           ...
/* * Normal ioctl processing */ }In the next example, the process has selected a condition and is blocked. Then, the condition becomes satisfied (read case handled):xx_selread(dev_t dev); { extern void selsuccess(); extern void selfailure(); struct proc *procp; struct xx_selstr *ptr = &xxselstr[dev]; if ( xx_condition_is_satisfied_for_read[dev] ) { selsuccess(); return; } /* * Condition is unsatisfied; process will block. */
procp = ptr->read; if (procp && procp->p_wchan == (char*) &selwait) ptr->flags |= READ_COLLISION; else ptr->read = u.u_procp; selfailure(); }
   xxintr(level)
   {
       ...
   
       /*
        * Driver first notices that the condition is now
        * satisfied and computes minor dev
        */
   
       xxwakeread(dev);
       ...
   }
   
   xxwakeread(dev_t dev);
   {
       struct xx_selstr *ptr = &xxselstr[dev];
   
       /*
        * If a proc has selected the condition, awaken it.
        */
   
       if (ptr->read)
       {
           selwakeup(ptr->read, ptr->flags & READ_COLLISION);
           ptr->read = (struct proc *) NULL;
           ptr->flags &= ~READ_COLLISION;
       }
   }