-- 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: -- -- -- -- WARNINGS: -- -- -- -- TODO: -- -- -- -- 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