SCO OpenServer


select: selsuccess, selfailure, selwakeup -- kernel routines supporting select(S)


#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.


Pointer to a process table entry which is found in the xxselstr data structure. Each time a process selects a condition that is not immediately satisfied, a pointer to the process must be stored in the data structure by a corresponding user-supplied routine: for example xx_selread, xx_selwrite, or xx_selexcept. This pointer is passed to the select(S) system call by the selwakeup call.

Byte used to indicate if multiple processes are colliding by selecting the same condition. Whenever more than one process selects a condition, the driver must set the correct collision bit. The three bits defined in the <sys/select.h> header file are READ_COLLISION, WRITE_COLLISION and EXCEPT_COLLISION, for selecting for reading, writing, and exceptional conditions, respectively.

Return values



The mode argument to the ioctl( ) call indicates the condition being selected; valid values are: SELREAD, SELWRITE, and SELEXCEPT. All drivers that support select( ) must implement the IOC_SELECT ioctl with code similar to that displayed in ``Examples'', below.

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;

Context and synchronization

User context.

Hardware applicability


Version applicability

oddi: 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

SVR5 DDI compatibility

These functions have no equivalent for DDI.




In the first example, a process issues the select(S) system call (read case only) which in turn calls xxioctl(dev, IOC_SELECT, ...). Note that the examples can be replicated for the other possible conditions by substituting ``write'' or ``except'' for all occurrences of ``read''.
        * 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

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(); }

In the next example, the process has selected a condition and is blocked. Then, the condition becomes satisfied (read case handled):

/* * 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; } }

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005