.\" @sel_rmfile
.\" @sel_addtimer
.\" @sel_rmtimer
+.\" @sel_addhook
+.\" @sel_rmhook
+.\" @sel_fdmerge
.\" @sel_select
.SH SYNOPSIS
.nf
.BI " void (*" func ")(struct timeval *" tv ", void *" p ),
.BI "void sel_rmtimer(sel_timer *" t );
+.BI "void sel_addhook(sel_state *" s ", sel_hook *" h ,
+.BI " sel_hookfn " before ", sel_hookfn " after ,
+.BI " void *" p );
+.BI "void sel_rmhook(sel_hook *" h );
+
+.BI "int sel_fdmerge(fd_set *" dest ", fd_set *" fd ", int " maxfd );
+
.BI "int sel_select(sel_state *" s );
.fi
.SH "OVERVIEW"
.B sel_initfile
function. This requires a large number of arguments:
.TP
-.I s
+.BI "sel_state *" s
A pointer to the multiplexor with which the file selector will be
associated. This is stored in the selector so that the multiplexor
argument can be omitted from later calls.
.TP
-.I f
+.BI "sel_file *" f
Pointer to the file selector object to be initialized.
.TP
-.I fd
+.BI "int " fd
The file descriptor which the selector is meant to watch.
.TP
-.I mode
+.BI "unsigned " mode
A constant describing which condition the selector is interested in.
This must be one of the
.B SEL_
constants described below.
.TP
-.I func
+.BI "void (*" func ")(int " fd ", unsigned " mode ", void *" p );
The handler function which is called when the appropriate condition
occurs on the file. This function's interface is described in more
detail below.
.TP
-.I p
+.BI "void *" p
An arbitrary pointer argument passed to
.I func
when it's called. Beyond this, no meaning is attached to the value of
.B sel_addtimer
requires lots of arguments:
.TP
-.I s
+.BI "sel_state *" s
Pointer to the multiplexor to which the selector is to be added.
.TP
-.I t
+.BI "sel_timer *" t
Pointer to the timer selector object being initialized and added.
.TP
-.I tv
-A
-.B "struct timeval"
-object describing when the selector should raise its event. This is an
+.BI "struct timeval " tv
+When the selector should raise its event. This is an
.I absolute
time, not a relative time as required by the traditional
.BR select (2)
.BR poll (2)
system calls.
.TP
-.I func
+.BI "void (*" func ")(struct timeval *" tv ", void *" p )
A handler function to be called when the event occurs. The function is
passed the
.I current
.I p
argument.
.TP
-.I p
+.BI "void *" p
A pointer passed to
.I func
when the timer event occurs. Beyond this, the value of the pointer is
returns zero. Otherwise it returns -1, and the global variable
.B errno
is set appropriately.
+.SH "SELECT HOOK FUNCTIONS"
+In order to interface other I/O multiplexing systems to this one, it's
+possible to register
+.I hook
+functions which are called before and after each
+.BR select (2)
+system call.
+.PP
+The function
+.B sel_addhook
+registers a pair of hook functions. It is passed the pointer to the
+multiplexor which is being hooked, the address of a
+.B sel_hook
+structure which will be used to record the hook information, the two
+hook functions (either of which may be a null pointer, signifying no
+action to be taken), and a pointer argument to be passed to the hook
+functions.
+.PP
+The function
+.B sel_rmhook
+removes a pair of hooks given the address of the
+.B sel_hook
+structure which recorded their registration.
+.PP
+A
+.I "hook function"
+is passed three arguments:
+.TP
+.BI "sel_state *" s
+A pointer to the multiplexor block. This probably isn't very useful,
+actually.
+.TP
+.BI "sel_args *" a
+A pointer to a block containing proposed arguments for, or results from,
+.BR select (2).
+The format of this block is described below.
+.TP
+.BI "void *" p
+A pointer argument set up in the call to
+.B sel_addhook
+to provide the hook function with some context.
+.PP
+The argument block contains the following members:
+.TP
+.B "int maxfd"
+One greater than the highest-numbered file descriptor to be examined.
+This may need to be modified if the file descriptor sets are altered.
+.TP
+.B "fd_set fd[SEL_MODES]"
+A file descriptor set for each of
+.BR SEL_READ ,
+.B SEL_WRITE
+and
+.BR SEL_EXC .
+Before the
+.B select
+call, these may be modified to register an interest in other file
+descriptors. Afterwards, they may be examined to decide which file
+descriptors are active.
+.TP
+.B "struct timeval tv, *tvp"
+Before the
+.B select
+call, these specify the time after which to return even if no files are
+active. If
+.B tvp
+is null, there is no timeout, and
+.B select
+should wait forever if necessary. Otherwise
+.B tvp
+should contain the address of
+.BR tv ,
+and
+.B tv
+should contain the timeout. After the
+.B select
+call, the contents of
+.B tv
+are undefined.
+.TP
+.B "struct timeval now"
+Before the
+.B select
+call, contains the current time. After the call, this will have been
+updated to reflect the new current time only if there was a timeout
+set before the call.
+.PP
+Hook functions may find the call
+.B sel_fdmerge
+useful. Given two file descriptor sets
+.I dest
+and
+.IR fd ,
+and a possibly overestimated highest file descriptor in
+.IR fd ,
+the function sets in
+.I dest
+all of the descriptors set in
+.I fd
+and returns an accurate file descriptor count as its result.
.SH "OTHER NOTES"
Although the naming seems to suggest that this is all
based around the BSD-ish
system call (and indeed it is), the interface is actually a good deal
more general than that. An implementation which worked off System V-ish
.BR poll (2)
-instead would be fairly trivial to make, and would look just the same
-from the outside.
+instead would be possible to make, and would look just the same from the
+outside. Some work would be needed to make the hook functions work,
+though.
.SH "SEE ALSO"
.BR select (2),
.BR poll (2),
.BR sig_add ,
passing it the following arguments:
.TP
-.I s
+.BI "sig *" s
A pointer to an (uninitialized) object of type
.BR sig .
This will be used by the system to retain information about this signal
claim. You use the address of this object to remove the handler again
when you've finished.
.TP
-.I n
+.BI "int " n
The number of the signal you want to handle.
.PP
.TP
-.I proc
+.BI "void (*" proc ")(int " n ", void *" p )
A function to call when the signal is detected. The function is passed
the signal number and the pointer
.I p
passed to
.BR sig_add .
.TP
-.I p
+.BI "void *" p
A pointer argument to be passed to
.I func
when the signal is detected.
.B SA_NOCLDSTOP
flag is also set, so that stopped child processes aren't reported by a
signal. This is normally right, but ought to be configurable.
-.PP
-The system uses writes to a nonblocking pipe to integrate with the I/O
-multiplexing system. It's possible (though very unlikely) that signals
-get lost because the pipe is full.
.SH "AUTHOR"
Mark Wooding, <mdw@nsict.org>