-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Wrap the select(2) POSIX function
--
-- While tinkering on a project, I frequently found myself having to make
-- FFI calls to select(2). This package provides an interface to
-- that system call.
--
-- Changes in version 0.4:
--
--
-- - Introduce an interface to fd_set.
-- - Add functions with various amounts of abstraction; in particular,
-- select'' matches select in previous versions.
-- - Retry select(2) in case of interruption by signals.
-- - Remove dependence on the vector package.
--
--
-- WARNINGS:
--
--
-- - Behavior with write and exception file descriptors is
-- under-tested. Feedback is welcome.
-- - This package is far from complete, and should be tested throughly
-- before being relied upon.
--
--
-- TODO:
--
--
-- - Return the error code specified by errno if select
-- fails.
-- - Possibly move the select retry code from C to Haskell.
-- - Reorder functions to make the documentation more logical.
-- - Use hsc2hs's #const to get preprocessor constants (removes some of
-- FdSet's cbits.c).
--
--
-- NOTE: I feel I'm occupying prime namespace realestate with a
-- package name like select. I'll happily let myself be chased away if
-- someone more qualified wants to use this package name. Let me know.
@package select
@version 0.4
-- | Interface to fd_set. See select(2).
--
-- The type FdSet is opaque, but is implemented internally as a
-- pointer to an fd_set. All operations on FdSets must
-- adhere to the requirements of FD_CLR, FD_ISSET,
-- FD_SET and FD_ZERO (see select(2)). This
-- includes requiring valid file descriptors for all operations.
-- Most functions in this module are kept in the IO monad to make
-- it easier to guarantee validity of the file descriptors, but since
-- invalid ones seem to work fine in practice (at least on Linux), the
-- module System.Posix.IO.Select.FdSet.Unsafe provides a
-- non-IO interface.
--
-- Functions that return an FdSet, such as insert, copy the
-- underlying fd_set in order to be referentially transparent.
--
-- In the documentation that follows, a file descriptor is said to be
-- in range if it is non-negative and strictly smaller than the
-- system-defined FD_SETSIZE. Many functions silently ignore
-- file descriptors that are not in range.
module System.Posix.IO.Select.FdSet
data FdSet
-- | Create an FdSet from a list of file descriptors. File
-- descriptors not in range (see above) are silently ignored.
fromList :: [Fd] -> IO FdSet
-- | Insert a file descriptor.
insert :: Fd -> FdSet -> IO FdSet
-- | Insert multiple file descriptors. This is more efficient than multiple
-- inserts (only a single copy of the set is made).
insertList :: [Fd] -> FdSet -> IO FdSet
-- | An empty FdSet.
empty :: IO FdSet
-- | Test for membership. Recall that POSIX allows undefined behavior if
-- the file descriptor is not valid (it does, however, seem to work fine
-- on Linux).
elem :: Fd -> FdSet -> IO Bool
-- | Remove a file descriptor.
remove :: Fd -> FdSet -> IO FdSet
-- | Remove multiple file descriptors. This is more efficient than multiple
-- removes (only a single copy of the set is made).
removeList :: [Fd] -> FdSet -> IO FdSet
-- | inList fds fdset gives a list of all file descriptors
-- in fd that are in fdset.
inList :: [Fd] -> FdSet -> IO [Fd]
-- | Test if a file descriptor is in range (see introduction).
inRange :: Fd -> Bool
-- | This file descriptor is at least as large as the largest in the set.
-- If no file descriptors have ever been removed from the set, the value
-- is the largest in the set, but this assumption may not hold
-- after removals or other operations.
bound :: FdSet -> Fd
-- | Copy an FdSet.
duplicate :: FdSet -> IO FdSet
-- | Pure interface to fd_set.
--
-- As far as I can tell, the data structure and functions in
-- System.Posix.IO.Select.FdSet are referentially transparent, and
-- it should be OK to escape the IO monad. However, POSIX requires
-- that all operations on fd_sets are done with valid
-- file descriptors. This can potentially be hard to ensure with lazy
-- evaluation in a pure setting, so for now this module bears the unsafe
-- label. On Linux, invalid file descriptors seem to be just fine.
--
-- See System.Posix.IO.Select.FdSet for documentation in general.
-- All functions here essentially just add unsafePerformIO.
module System.Posix.IO.Select.FdSet.Unsafe
data FdSet
fromList :: [Fd] -> FdSet
insert :: Fd -> FdSet -> FdSet
insertList :: [Fd] -> FdSet -> FdSet
elem :: Fd -> FdSet -> Bool
remove :: Fd -> FdSet -> FdSet
removeList :: [Fd] -> FdSet -> FdSet
inList :: [Fd] -> FdSet -> [Fd]
empty :: FdSet
-- | This converts an FdSet to a list by testing every file
-- descriptor in range for membership, which tends to involve invalid
-- file descriptors, giving undefined behavior according to POSIX. Use
-- inList if possible.
unsafeToList :: FdSet -> [Fd]
-- | Various types.
module System.Posix.IO.Select.Types
-- | A timeout of Never tells select(2) to never
-- time out, while Time sets a finite timeout.
data Timeout
Never :: Timeout
Time :: CTimeval -> Timeout
-- | A Storable instance for struct timeval (see
-- select(2)). The first argument corresponds to
-- tv_sec, the second to tv_usec.
data CTimeval
CTimeval :: CLong -> CLong -> CTimeval
-- | finite s us tells select to time out after
-- s seconds and us microseconds.
finite :: CLong -> CLong -> Timeout
-- | Abstraction for the return value of select.
-- Error means that select returned an error,
-- while Timeout means it timed out. Ready n rfds wfds
-- efds specifies that it returned because the file descriptors in
-- rfds, wfds and efds are ready in their
-- respective ways (see select(2)), with n descriptors
-- in total.
data Result
Error :: Result
Timeout :: Result
Ready :: CInt -> FdSet -> FdSet -> FdSet -> Result
-- | The total number of ready file descriptors across all three sets.
numReady :: Result -> CInt
-- | The file descriptors ready for reading.
readyRead :: Result -> FdSet
-- | The file descriptors ready for writing.
readyWrite :: Result -> FdSet
-- | The file descriptors having exceptional conditions.
readyException :: Result -> FdSet
instance Storable CTimeval
-- | Interface to select(2). The arguments to the functions
-- exposed here must fulfill the same requirements as the arguments for
-- select itself; see the man page.
--
-- If the select call made by any of these functions is
-- interrupted (select returning -1 and errno
-- being EINTR) before the given time has elapsed, the call will
-- be retried. If the specified amount of time has passed and
-- select is still being interrupted, the functions below will
-- make one last attempt with timeout zero. If that call too is
-- interrupted, behavior will be as if select returned an error.
module System.Posix.IO.Select
-- | The first FdSet is watched for readiness to read, the second
-- for readiness to write, and the third for exceptions. The
-- Timeout argument specifies when select should time out
-- (if at all).
select :: FdSet -> FdSet -> FdSet -> Timeout -> IO Result
-- | A simpler version of select that uses file descriptor lists
-- instead of FdSets. Nothing is returned in case
-- select gives an error, otherwise Just (rfds, wfds,
-- efds) is returned, where rfds, wfds and
-- efds are lists of ready file descriptors (they may be empty,
-- such as in the case of select timing out).
select' :: [Fd] -> [Fd] -> [Fd] -> Timeout -> IO (Maybe ([Fd], [Fd], [Fd]))
-- | This simpler version of select takes the same arguments as
-- select', but only returns the return value of
-- select(2) itself (i.e. -1 on error, otherwise the
-- number of ready file descriptors in total).
select'' :: [Fd] -> [Fd] -> [Fd] -> Timeout -> IO CInt