+%************************************************************************
+%* *
+\section[syslibs]{System libraries}
+\index{system libraries}
+\index{libraries, system}
+%* *
+
+This section gives an overview of the interfaces provided
+by the different {\em syslibs} that comes bundled with GHC.
+
+At the moment, there four different collections of system libraries:
+
+\begin{itemize}
+\item The GHC system library - collection of interfaces that mainly
+have grown out of abstractions used to implement GHC itself.
+\item Parts of the HBC libraries.
+\item The Posix interface - a quality interface to OS functionality as
+specified by {\tt POSIX 1003.1}. Sadly, this library hasn't made it
+into a standard Haskell library.
+\item The contrib libraries - oodles of numeric codes..
+\end{itemize}
+
+If you provide a \tr{-syslib <name>}\index{-syslib <name> option}
+option on the command line, then the interfaces for that library will
+come into scope (and may be \tr{import}ed), and the code will be added
+in at link time.
+
+
+%************************************************************************
+%* *
+\subsection[GHC-library]{The GHC system library}
+\index{library, GHC}
+\index{GHC library}
+%* *
+%************************************************************************
+
+We have started to put together a ``GHC system library.''
+
+At the moment, the library is made of generally-useful bits of the
+compiler itself.
+
+To use this library, just give a \tr{-syslib ghc}\index{-syslib ghc option}
+option to GHC, both for compiling and linking.
+
+%************************************************************************
+%* *
+\subsubsection[Bag]{The @Bag@ type}
+\index{Bag module (GHC syslib)}
+%* *
+%************************************************************************
+
+A {\em bag} is an unordered collection of elements which may contain
+duplicates. To use, \tr{import Bag}.
+
+\begin{verbatim}
+data Bag elt -- abstract
+
+emptyBag :: Bag elt
+unitBag :: elt -> Bag elt
+
+consBag :: elt -> Bag elt -> Bag elt
+snocBag :: Bag elt -> elt -> Bag elt
+
+unionBags :: Bag elt -> Bag elt -> Bag elt
+unionManyBags :: [Bag elt] -> Bag elt
+
+isEmptyBag :: Bag elt -> Bool
+elemBag :: Eq elt => elt -> Bag elt -> Bool
+
+filterBag :: (elt -> Bool) -> Bag elt -> Bag elt
+partitionBag :: (elt -> Bool) -> Bag elt-> (Bag elt, Bag elt)
+ -- returns the elements that do/don't satisfy the predicate
+
+concatBag :: Bag (Bag a) -> Bag a
+foldBag :: (r -> r -> r) -> (a -> r) -> r -> Bag a -> r
+mapBag :: (a -> b) -> Bag a -> Bag b
+
+listToBag :: [elt] -> Bag elt
+bagToList :: Bag elt -> [elt]
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[FiniteMap]{The @FiniteMap@ type}
+\index{FiniteMap module (GHC syslib)}
+%* *
+%************************************************************************
+
+What functional programmers call a {\em finite map}, everyone else
+calls a {\em lookup table}.
+
+Out code is derived from that in this paper:
+\begin{display}
+S Adams
+"Efficient sets: a balancing act"
+Journal of functional programming 3(4) Oct 1993, pages 553-562
+\end{display}
+Guess what? The implementation uses balanced trees.
+
+\begin{verbatim}
+data FiniteMap key elt -- abstract
+
+-- BUILDING
+emptyFM :: FiniteMap key elt
+unitFM :: key -> elt -> FiniteMap key elt
+listToFM :: Ord key => [(key,elt)] -> FiniteMap key elt
+ -- In the case of duplicates, the last is taken
+
+-- ADDING AND DELETING
+ -- Throws away any previous binding
+ -- In the list case, the items are added starting with the
+ -- first one in the list
+addToFM :: Ord key => FiniteMap key elt -> key -> elt -> FiniteMap key elt
+addListToFM :: Ord key => FiniteMap key elt -> [(key,elt)] -> FiniteMap key elt
+
+ -- Combines with previous binding
+ -- In the combining function, the first argument is
+ -- the "old" element, while the second is the "new" one.
+addToFM_C :: Ord key => (elt -> elt -> elt)
+ -> FiniteMap key elt -> key -> elt
+ -> FiniteMap key elt
+addListToFM_C :: Ord key => (elt -> elt -> elt)
+ -> FiniteMap key elt -> [(key,elt)]
+ -> FiniteMap key elt
+
+ -- Deletion doesn't complain if you try to delete something
+ -- which isn't there
+delFromFM :: Ord key => FiniteMap key elt -> key -> FiniteMap key elt
+delListFromFM :: Ord key => FiniteMap key elt -> [key] -> FiniteMap key elt
+
+-- COMBINING
+ -- Bindings in right argument shadow those in the left
+plusFM :: Ord key => FiniteMap key elt -> FiniteMap key elt
+ -> FiniteMap key elt
+
+ -- Combines bindings for the same thing with the given function
+plusFM_C :: Ord key => (elt -> elt -> elt)
+ -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
+
+minusFM :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
+ -- (minusFM a1 a2) deletes from a1 any bindings which are bound in a2
+
+intersectFM :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
+intersectFM_C :: Ord key => (elt -> elt -> elt)
+ -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
+
+-- MAPPING, FOLDING, FILTERING
+foldFM :: (key -> elt -> a -> a) -> a -> FiniteMap key elt -> a
+mapFM :: (key -> elt1 -> elt2) -> FiniteMap key elt1 -> FiniteMap key elt2
+filterFM :: Ord key => (key -> elt -> Bool)
+ -> FiniteMap key elt -> FiniteMap key elt
+
+-- INTERROGATING
+sizeFM :: FiniteMap key elt -> Int
+isEmptyFM :: FiniteMap key elt -> Bool
+
+elemFM :: Ord key => key -> FiniteMap key elt -> Bool
+lookupFM :: Ord key => FiniteMap key elt -> key -> Maybe elt
+lookupWithDefaultFM
+ :: Ord key => FiniteMap key elt -> elt -> key -> elt
+ -- lookupWithDefaultFM supplies a "default" elt
+ -- to return for an unmapped key
+
+-- LISTIFYING
+fmToList :: FiniteMap key elt -> [(key,elt)]
+keysFM :: FiniteMap key elt -> [key]
+eltsFM :: FiniteMap key elt -> [elt]
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[ListSetOps]{The @ListSetOps@ type}
+\index{ListSetOps module (GHC syslib)}
+%* *
+%************************************************************************
+
+Just a few set-sounding operations on lists. If you want sets, use
+the \tr{Set} module.
+
+\begin{verbatim}
+unionLists :: Eq a => [a] -> [a] -> [a]
+intersectLists :: Eq a => [a] -> [a] -> [a]
+minusList :: Eq a => [a] -> [a] -> [a]
+disjointLists :: Eq a => [a] -> [a] -> Bool
+intersectingLists :: Eq a => [a] -> [a] -> Bool
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[Maybes]{The @Maybes@ type}
+\index{Maybes module (GHC syslib)}
+%* *
+%************************************************************************
+
+The \tr{Maybe} type is in the Haskell 1.4 prelude. Moreover, the
+required \tr{Maybe} library provides many useful functions on
+\tr{Maybe}s. This (pre-1.3) module provides some more:
+
+An \tr{Either}-like type called \tr{MaybeErr}:
+\begin{verbatim}
+data MaybeErr val err = Succeeded val | Failed err
+\end{verbatim}
+
+Some operations to do with \tr{Maybe} (some commentary follows):
+\begin{verbatim}
+maybeToBool :: Maybe a -> Bool -- Nothing => False; Just => True
+allMaybes :: [Maybe a] -> Maybe [a]
+firstJust :: [Maybe a] -> Maybe a
+findJust :: (a -> Maybe b) -> [a] -> Maybe b
+
+assocMaybe :: Eq a => [(a,b)] -> a -> Maybe b
+mkLookupFun :: (key -> key -> Bool) -- Equality predicate
+ -> [(key,val)] -- The assoc list
+ -> (key -> Maybe val) -- A lookup fun to use
+mkLookupFunDef :: (key -> key -> Bool) -- Equality predicate
+ -> [(key,val)] -- The assoc list
+ -> val -- Value to return on failure
+ -> key -- The key
+ -> val -- The corresponding value
+
+ -- a monad thing
+thenMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
+returnMaybe :: a -> Maybe a
+failMaybe :: Maybe a
+mapMaybe :: (a -> Maybe b) -> [a] -> Maybe [b]
+\end{verbatim}
+
+NB: @catMaybes@ which used to be here, is now available via the
+standard @Maybe@ interface (@Maybe@ is an instance of @MonadPlus@).
+
+@allMaybes@ collects a list of @Justs@ into a single @Just@, returning
+@Nothing@ if there are any @Nothings@.
+
+@firstJust@ takes a list of @Maybes@ and returns the
+first @Just@ if there is one, or @Nothing@ otherwise.
+
+@assocMaybe@ looks up in an association list, returning
+@Nothing@ if it fails.
+
+Now, some operations to do with \tr{MaybeErr} (comments follow):
+\begin{verbatim}
+ -- a monad thing (surprise, surprise)
+thenMaB :: MaybeErr a err -> (a -> MaybeErr b err) -> MaybeErr b err
+returnMaB :: val -> MaybeErr val err
+failMaB :: err -> MaybeErr val err
+
+listMaybeErrs :: [MaybeErr val err] -> MaybeErr [val] [err]
+foldlMaybeErrs :: (acc -> input -> MaybeErr acc err)
+ -> acc
+ -> [input]
+ -> MaybeErr acc [err]
+\end{verbatim}
+
+@listMaybeErrs@ takes a list of @MaybeErrs@ and, if they all succeed,
+returns a @Succeeded@ of a list of their values. If any fail, it
+returns a @Failed@ of the list of all the errors in the list.
+
+@foldlMaybeErrs@ works along a list, carrying an accumulator; it
+applies the given function to the accumulator and the next list item,
+accumulating any errors that occur.
+
+%************************************************************************
+%* *
+\subsubsection[PackedString]{The @PackedString@ type}
+\index{PackedString module (GHC syslib)}
+%* *
+%************************************************************************
+
+You need to \tr{import PackedString} and heave in your \tr{-syslib
+ghc} to use \tr{PackedString}s.
+
+The basic type and functions available are:
+\begin{verbatim}
+data PackedString -- abstract
+
+packString :: [Char] -> PackedString
+packStringST :: [Char] -> ST s PackedString
+packCBytesST :: Int -> Addr -> ST s PackedString
+packBytesForCST :: [Char] -> ST s (ByteArray Int)
+byteArrayToPS :: ByteArray Int -> PackedString
+unsafeByteArrayToPS :: ByteArray a -> Int -> PackedString
+psToByteArray :: PackedString -> ByteArray Int
+psToByteArrayST :: PackedString -> ST s (ByteArray Int)
+
+unpackPS :: PackedString -> [Char]
+\end{verbatim}
+
+We also provide a wad of list-manipulation-like functions:
+\begin{verbatim}
+nilPS :: PackedString
+consPS :: Char -> PackedString -> PackedString
+
+headPS :: PackedString -> Char
+tailPS :: PackedString -> PackedString
+nullPS :: PackedString -> Bool
+appendPS :: PackedString -> PackedString -> PackedString
+lengthPS :: PackedString -> Int
+indexPS :: PackedString -> Int -> Char
+ -- 0-origin indexing into the string
+mapPS :: (Char -> Char) -> PackedString -> PackedString
+filterPS :: (Char -> Bool) -> PackedString -> PackedString
+foldlPS :: (a -> Char -> a) -> a -> PackedString -> a
+foldrPS :: (Char -> a -> a) -> a -> PackedString -> a
+takePS :: Int -> PackedString -> PackedString
+dropPS :: Int -> PackedString -> PackedString
+splitAtPS :: Int -> PackedString -> (PackedString, PackedString)
+takeWhilePS :: (Char -> Bool) -> PackedString -> PackedString
+dropWhilePS :: (Char -> Bool) -> PackedString -> PackedString
+spanPS :: (Char -> Bool) -> PackedString -> (PackedString, PackedString)
+breakPS :: (Char -> Bool) -> PackedString -> (PackedString, PackedString)
+linesPS :: PackedString -> [PackedString]
+wordsPS :: PackedString -> [PackedString]
+reversePS :: PackedString -> PackedString
+concatPS :: [PackedString] -> PackedString
+elemPS :: Char -> PackedString -> Bool
+ -- Perl-style split&join
+splitPS :: Char -> PackedString -> [PackedString]
+splitWithPS :: (Char -> Bool) -> PackedString -> [PackedString]
+joinPS :: PackedString -> [PackedString] -> PackedString
+
+substrPS :: PackedString -> Int -> Int -> PackedString
+ -- pluck out a piece of a PackedString
+ -- start and end chars you want; both 0-origin-specified
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[Pretty]{The @Pretty@ type}
+\index{Pretty module (GHC syslib)}
+%* *
+%************************************************************************
+
+This is the pretty-printer that is currently used in GHC:
+
+\begin{verbatim}
+type Pretty
+
+ppShow :: Int{-width-} -> Pretty -> [Char]
+
+pp'SP :: Pretty -- "comma space"
+ppComma :: Pretty -- ,
+ppEquals :: Pretty -- =
+ppLbrack :: Pretty -- [
+ppLparen :: Pretty -- (
+ppNil :: Pretty -- nothing
+ppRparen :: Pretty -- )
+ppRbrack :: Pretty -- ]
+ppSP :: Pretty -- space
+ppSemi :: Pretty -- ;
+
+ppChar :: Char -> Pretty
+ppDouble :: Double -> Pretty
+ppFloat :: Float -> Pretty
+ppInt :: Int -> Pretty
+ppInteger :: Integer -> Pretty
+ppRational :: Rational -> Pretty
+ppStr :: [Char] -> Pretty
+
+ppAbove :: Pretty -> Pretty -> Pretty
+ppAboves :: [Pretty] -> Pretty
+ppBeside :: Pretty -> Pretty -> Pretty
+ppBesides :: [Pretty] -> Pretty
+ppCat :: [Pretty] -> Pretty
+ppHang :: Pretty -> Int -> Pretty -> Pretty
+ppInterleave :: Pretty -> [Pretty] -> Pretty -- spacing between
+ppIntersperse :: Pretty -> [Pretty] -> Pretty -- no spacing between
+ppNest :: Int -> Pretty -> Pretty
+ppSep :: [Pretty] -> Pretty
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[Set]{The @Set@ type}
+\index{Set module (GHC syslib)}
+%* *
+%************************************************************************
+
+Our implementation of {\em sets} (key property: no duplicates) is just
+a variant of the \tr{FiniteMap} module.
+
+\begin{verbatim}
+data Set -- abstract
+ -- instance of: Eq
+
+emptySet :: Set a
+mkSet :: Ord a => [a] -> Set a
+setToList :: Set a -> [a]
+unitSet :: a -> Set a
+singletonSet :: a -> Set a -- deprecated, use unitSet.
+
+union :: Ord a => Set a -> Set a -> Set a
+unionManySets :: Ord a => [Set a] -> Set a
+minusSet :: Ord a => Set a -> Set a -> Set a
+mapSet :: Ord a => (b -> a) -> Set b -> Set a
+intersect :: Ord a => Set a -> Set a -> Set a
+
+elementOf :: Ord a => a -> Set a -> Bool
+isEmptySet :: Set a -> Bool
+
+cardinality :: Set a -> Int
+
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[BitSet]{The @BitSet@ interface}
+\index{Bitset interface (GHC syslib)}
+%* *
+%************************************************************************
+
+Bit sets are a fast implementation of sets of integers ranging from 0
+to one less than the number of bits in a machine word (typically 31).
+If any element exceeds the maximum value for a particular machine
+architecture, the results of these operations are undefined. You have
+been warned.
+
+\begin{verbatim}
+data BitSet -- abstract
+ -- instance of:
+
+emptyBS :: BitSet
+mkBS :: [Int] -> BitSet
+unitBS :: Int -> BitSet
+unionBS :: BitSet -> BitSet -> BitSet
+minusBS :: BitSet -> BitSet -> BitSet
+isEmptyBS :: BitSet -> Bool
+intersectBS :: BitSet -> BitSet -> BitSet
+elementBS :: Int -> BitSet -> Bool
+listBS :: BitSet -> [Int]
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[Util]{The @Util@ type}
+\index{Util module (GHC syslib)}
+%* *
+%************************************************************************
+
+Stuff that has been generally useful to use in writing the compiler.
+Don't be too surprised if this stuff moves/gets-renamed/etc.
+
+\begin{verbatim}
+-- general list processing
+forall :: (a -> Bool) -> [a] -> Bool
+exists :: (a -> Bool) -> [a] -> Bool
+
+nOfThem :: Int -> a -> [a]
+lengthExceeds :: [a] -> Int -> Bool
+isSingleton :: [a] -> Bool
+
+--paranoid zip'ing (equal length lists)
+zipEqual :: [a] -> [b] -> [(a,b)]
+zipWithEqual :: String -> (a->b->c) -> [a]->[b]->[c]
+zipWith3Equal :: String -> (a->b->c->d) -> [a]->[b]->[c]->[d]
+zipWith4Equal :: String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
+-- lazy in second argument
+zipLazy :: [a] -> [b] -> [(a,b)]
+
+mapAndUnzip :: (a -> (b, c)) -> [a] -> ([b], [c])
+mapAndUnzip3 :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d])
+
+-- prefix and suffix matching on lists of characters.
+startsWith :: {-prefix-}String -> String -> Maybe String
+endsWith :: {-suffix-}String -> String -> Maybe String
+
+-- association lists
+assoc :: Eq a => String -> [(a, b)] -> a -> b
+
+-- duplicate handling
+hasNoDups :: Eq a => [a] -> Bool
+equivClasses :: (a -> a -> Ordering) -> [a] -> [[a]]
+runs :: (a -> a -> Bool) -> [a] -> [[a]]
+removeDups :: (a -> a -> Ordering) -> [a] -> ([a], [[a]])
+
+-- sorting (don't complain of no choice...)
+quicksort :: (a -> a -> Bool) -> [a] -> [a]
+sortLt :: (a -> a -> Bool) -> [a] -> [a]
+stableSortLt :: (a -> a -> Bool) -> [a] -> [a]
+mergesort :: (a -> a -> _CMP_TAG) -> [a] -> [a]
+mergeSort :: Ord a => [a] -> [a]
+naturalMergeSort :: Ord a => [a] -> [a]
+mergeSortLe :: Ord a => [a] -> [a]
+naturalMergeSortLe :: Ord a => [a] -> [a]
+
+-- transitive closures
+transitiveClosure :: (a -> [a]) -- Successor function
+ -> (a -> a -> Bool) -- Equality predicate
+ -> [a]
+ -> [a] -- The transitive closure
+
+-- accumulating (Left, Right, Bi-directional)
+mapAccumL :: (acc -> x -> (acc, y))
+ -- Function of elt of input list and
+ -- accumulator, returning new accumulator and
+ -- elt of result list
+ -> acc -- Initial accumulator
+ -> [x] -- Input list
+ -> (acc, [y]) -- Final accumulator and result list
+
+mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
+
+mapAccumB :: (accl -> accr -> x -> (accl, accr,y))
+ -> accl -> accr -> [x]
+ -> (accl, accr, [y])
+
+--list comparison with explicit element comparer.
+cmpList :: (a -> a -> Ordering) -> [a] -> [a] -> Ordering
+
+-- pairs
+applyToPair :: ((a -> c), (b -> d)) -> (a, b) -> (c, d)
+applyToFst :: (a -> c) -> (a, b) -> (c, b)
+applyToSnd :: (b -> d) -> (a, b) -> (a, d)
+foldPair :: (a->a->a, b->b->b) -> (a, b) -> [(a, b)] -> (a, b)
+unzipWith :: (a -> b -> c) -> [(a, b)] -> [c]
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsection[C-interfaces]{Interfaces to C libraries}
+\index{C library interfaces}
+\index{interfaces, C library}
+%* *
+%************************************************************************
+
+The GHC system library (\tr{-syslib ghc}) also provides interfaces to
+several useful C libraries, mostly from the GNU project.
+
+%************************************************************************
+%* *
+\subsubsection[Readline]{The @Readline@ interface}
+\index{Readline library (GHC syslib)}
+\index{command-line editing library}
+%* *
+%************************************************************************
+
+(Darren Moffat supplied the \tr{Readline} interface.)
+
+The \tr{Readline} module is a straightforward interface to the GNU
+Readline library. As such, you will need to look at the GNU
+documentation (and have a \tr{libreadline.a} file around somewhere...)
+
+You'll need to link any Readlining program with \tr{-lreadline -ltermcap},
+besides the usual \tr{-syslib ghc} (and \tr{-fhaskell-1.3}).
+
+The main function you'll use is:
+\begin{verbatim}
+readline :: String{-the prompt-} -> IO String
+\end{verbatim}
+
+If you want to mess around with Full Readline G(l)ory, we also
+provide:
+\begin{verbatim}
+rlInitialize, addHistory,
+
+rlBindKey, rlAddDefun, RlCallbackFunction(..),
+
+rlGetLineBuffer, rlSetLineBuffer, rlGetPoint, rlSetPoint, rlGetEnd,
+rlSetEnd, rlGetMark, rlSetMark, rlSetDone, rlPendingInput,
+
+rlPrompt, rlTerminalName, rlSetReadlineName, rlGetReadlineName
+\end{verbatim}
+(All those names are just Haskellised versions of what you
+will see in the GNU readline documentation.)
+
+%************************************************************************
+%* *
+\subsubsection[Regexp]{The @Regexp@ and @MatchPS@ interfaces}
+\index{Regex library (GHC syslib)}
+\index{MatchPS library (GHC syslib)}
+\index{regular-expressions library}
+%* *
+%************************************************************************
+
+(Sigbjorn Finne supplied the regular-expressions interface.)
+
+The \tr{Regex} library provides quite direct interface to the GNU
+regular-expression library, for doing manipulation on
+\tr{PackedString}s. You probably need to see the GNU documentation
+if you are operating at this level.
+
+The datatypes and functions that \tr{Regex} provides are:
+\begin{verbatim}
+data PatBuffer # just a bunch of bytes (mutable)
+
+data REmatch
+ = REmatch (Array Int GroupBounds) -- for $1, ... $n
+ GroupBounds -- for $` (everything before match)
+ GroupBounds -- for $& (entire matched string)
+ GroupBounds -- for $' (everything after)
+ GroupBounds -- for $+ (matched by last bracket)
+
+-- GroupBounds hold the interval where a group
+-- matched inside a string, e.g.
+--
+-- matching "reg(exp)" "a regexp" returns the pair (5,7) for the
+-- (exp) group. (PackedString indices start from 0)
+
+type GroupBounds = (Int, Int)
+
+re_compile_pattern
+ :: PackedString -- pattern to compile
+ -> Bool -- True <=> assume single-line mode
+ -> Bool -- True <=> case-insensitive
+ -> PrimIO PatBuffer
+
+re_match :: PatBuffer -- compiled regexp
+ -> PackedString -- string to match
+ -> Int -- start position
+ -> Bool -- True <=> record results in registers
+ -> PrimIO (Maybe REmatch)
+
+-- Matching on 2 strings is useful when you're dealing with multiple
+-- buffers, which is something that could prove useful for
+-- PackedStrings, as we don't want to stuff the contents of a file
+-- into one massive heap chunk, but load (smaller chunks) on demand.
+
+re_match2 :: PatBuffer -- 2-string version
+ -> PackedString
+ -> PackedString
+ -> Int
+ -> Int
+ -> Bool
+ -> PrimIO (Maybe REmatch)
+
+re_search :: PatBuffer -- compiled regexp
+ -> PackedString -- string to search
+ -> Int -- start index
+ -> Int -- stop index
+ -> Bool -- True <=> record results in registers
+ -> PrimIO (Maybe REmatch)
+
+re_search2 :: PatBuffer -- Double buffer search
+ -> PackedString
+ -> PackedString
+ -> Int -- start index
+ -> Int -- range (?)
+ -> Int -- stop index
+ -> Bool -- True <=> results in registers
+ -> PrimIO (Maybe REmatch)
+\end{verbatim}
+
+The \tr{MatchPS} module provides Perl-like ``higher-level'' facilities
+to operate on \tr{PackedStrings}. The regular expressions in
+question are in Perl syntax. The ``flags'' on various functions can
+include: \tr{i} for case-insensitive, \tr{s} for single-line mode, and
+\tr{g} for global. (It's probably worth your time to peruse the
+source code...)
+
+\begin{verbatim}
+matchPS :: PackedString -- regexp
+ -> PackedString -- string to match
+ -> [Char] -- flags
+ -> Maybe REmatch -- info about what matched and where
+
+searchPS :: PackedString -- regexp
+ -> PackedString -- string to match
+ -> [Char] -- flags
+ -> Maybe REmatch
+
+-- Perl-like match-and-substitute:
+substPS :: PackedString -- regexp
+ -> PackedString -- replacement
+ -> [Char] -- flags
+ -> PackedString -- string
+ -> PackedString
+
+-- same as substPS, but no prefix and suffix:
+replacePS :: PackedString -- regexp
+ -> PackedString -- replacement
+ -> [Char] -- flags
+ -> PackedString -- string
+ -> PackedString
+
+match2PS :: PackedString -- regexp
+ -> PackedString -- string1 to match
+ -> PackedString -- string2 to match
+ -> [Char] -- flags
+ -> Maybe REmatch
+
+search2PS :: PackedString -- regexp
+ -> PackedString -- string to match
+ -> PackedString -- string to match
+ -> [Char] -- flags
+ -> Maybe REmatch
+
+-- functions to pull the matched pieces out of an REmatch:
+
+getMatchesNo :: REmatch -> Int
+getMatchedGroup :: REmatch -> Int -> PackedString -> PackedString
+getWholeMatch :: REmatch -> PackedString -> PackedString
+getLastMatch :: REmatch -> PackedString -> PackedString
+getAfterMatch :: REmatch -> PackedString -> PackedString
+
+-- (reverse) brute-force string matching;
+-- Perl equivalent is index/rindex:
+findPS, rfindPS :: PackedString -> PackedString -> Maybe Int
+
+-- Equivalent to Perl "chop" (off the last character, if any):
+chopPS :: PackedString -> PackedString
+
+-- matchPrefixPS: tries to match as much as possible of strA starting
+-- from the beginning of strB (handy when matching fancy literals in
+-- parsers):
+matchPrefixPS :: PackedString -> PackedString -> Int
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsubsection[Socket]{Network-interface toolkit---@Socket@ and @SocketPrim@}
+\index{SocketPrim interface (GHC syslib)}
+\index{Socket interface (GHC syslib)}
+\index{network-interface library}
+\index{sockets library}
+\index{BSD sockets library}
+%* *
+%************************************************************************
+
+(Darren Moffat supplied the network-interface toolkit.)
+
+Your best bet for documentation is to look at the code---really!---
+normally in \tr{hslibs/ghc/src/{BSD,Socket,SocketPrim}.lhs}.
+
+The \tr{BSD} module provides functions to get at system-database info;
+pretty straightforward if you're into this sort of thing:
+\begin{verbatim}
+getHostName :: IO String
+
+getServiceByName :: ServiceName -> IO ServiceEntry
+getServicePortNumber:: ServiceName -> IO PortNumber
+getServiceEntry :: IO ServiceEntry
+setServiceEntry :: Bool -> IO ()
+endServiceEntry :: IO ()
+
+getProtocolByName :: ProtocolName -> IO ProtocolEntry
+getProtocolByNumber :: ProtocolNumber -> IO ProtcolEntry
+getProtocolNumber :: ProtocolName -> ProtocolNumber
+getProtocolEntry :: IO ProtocolEntry
+setProtocolEntry :: Bool -> IO ()
+endProtocolEntry :: IO ()
+
+getHostByName :: HostName -> IO HostEntry
+getHostByAddr :: Family -> HostAddress -> IO HostEntry
+getHostEntry :: IO HostEntry
+setHostEntry :: Bool -> IO ()
+endHostEntry :: IO ()
+\end{verbatim}
+
+The \tr{SocketPrim} interface provides quite direct access to the
+socket facilities in a BSD Unix system, including all the
+complications. We hope you don't need to use it! See the source if
+needed...
+
+The \tr{Socket} interface is a ``higher-level'' interface to sockets,
+and it is what we recommend. Please tell us if the facilities it
+offers are inadequate to your task!
+
+The interface is relatively modest:
+\begin{verbatim}
+connectTo :: Hostname -> PortID -> IO Handle
+listenOn :: PortID -> IO Socket
+
+accept :: Socket -> IO (Handle, HostName)
+sendTo :: Hostname -> PortID -> String -> IO ()
+
+recvFrom :: Hostname -> PortID -> IO String
+socketPort :: Socket -> IO PortID
+
+data PortID -- PortID is a non-abstract type
+ = Service String -- Service Name eg "ftp"
+ | PortNumber Int -- User defined Port Number
+ | UnixSocket String -- Unix family socket in file system
+
+type Hostname = String
+\end{verbatim}
+
+Various examples of networking Haskell code are provided in
+\tr{ghc/misc/examples/}, notably the \tr{net???/Main.hs} programs.
+
+%************************************************************************
+%* *
+\subsection[Posix-library]{The Posix system library}
+\index{Posix system library}
+\index{system library, Posix}
+%* *
+%************************************************************************
+
+The @Posix@ interface gives you access to the set of OS services
+standardised by POSIX 1003.1b (or the {\em IEEE Portable Operating System
+Interface for Computing Environments} - IEEE Std. 1003.1). The
+interface is accessed by \tr{import Posix} and adding \tr{-syslib
+posix} on your command-line.
+
+\subsubsection[Posix-data-types]{Posix data types}
+\index{Posix, data types}
+
+
+\begin{verbatim}
+data ByteCount -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{ByteCount} is a primitive of type \tr{unsigned}. At a minimum,
+an conforming implementation must support values in the range
+\tr{[0, UINT_MAX]}.
+
+\begin{verbatim}
+data ClockTick -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{ClockTick} is a primitive of type \tr{clock_t}, which
+is used to measure intervals of time in fractions of a second. The
+resolution is determined by \tr{getSysVar ClockTick}.
+
+\begin{verbatim}
+data DeviceID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{DeviceID} is a primitive of type \tr{dev_t}. It must
+be an arithmetic type.
+
+\begin{verbatim}
+> data EpochTime -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{EpochTime} is a primitive of type \tr{time_t}, which is
+used to measure seconds since the Epoch. At a minimum, the implementation
+must support values in the range \tr{[0, INT_MAX]}.
+
+\begin{verbatim}
+data FileID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{FileID} is a primitive of type \tr{ino_t}. It must
+be an arithmetic type.
+
+\begin{verbatim}
+data FileMode -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{FileMode} is a primitive of type \tr{mode_t}.
+It must be an arithmetic type.
+
+\begin{verbatim}
+data FileOffset -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{FileOffset} is a primitive of type \tr{off_t}. It must
+be an arithmetic type.
+
+\begin{verbatim}
+data GroupID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{GroupID} is a primitive of type \tr{gid_t}. It must
+be an arithmetic type.
+\begin{verbatim}
+data Limit -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{Limit} is a primitive of type \tr{long}.
+At a minimum, the implementation must support values in the range
+\tr{[LONG_MIN, LONG_MAX]}.
+
+\begin{verbatim}
+data LinkCount -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{LinkCount} is a primitive of type \tr{nlink_t}. It must
+be an arithmetic type.
+
+\begin{verbatim}
+data ProcessID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+type ProcessGroupID = ProcessID
+\end{verbatim}
+
+A \tr{ProcessID} is a primitive of type \tr{pid_t}. It
+must be a signed arithmetic type.
+\begin{verbatim}
+data UserID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+\end{verbatim}
+
+A \tr{UserID} is a primitive of type \tr{uid_t}. It
+must be an arithmetic type.
+
+\begin{verbatim}
+data DirStream
+\end{verbatim}
+A \tr{DirStream} is a primitive of type \tr{DIR *}.
+
+\begin{verbatim}
+data FileStatus
+\end{verbatim}
+A \tr{FileStatus} is a primitive of type \tr{struct stat}.
+
+\begin{verbatim}
+data GroupEntry
+\end{verbatim}
+
+A \tr{GroupEntry} is a primitive of type \tr{struct group}.
+\begin{verbatim}
+data ProcessTimes
+\end{verbatim}
+
+\tr{ProcessTimes} is a primitive structure containing a
+\tr{clock_t} and a \tr{struct tms}.
+
+\begin{verbatim}
+data SignalSet
+\end{verbatim}
+
+An \tr{SignalSet} is a primitive of type \tr{sigset_t}.
+
+\begin{verbatim}
+data SystemID
+\end{verbatim}
+
+A \tr{SystemID} is a primitive of type \tr{struct utsname}.
+
+\begin{verbatim}
+data TerminalAttributes
+\end{verbatim}
+\tr{TerminalAttributes} is a primitive of type \tr{struct termios}.
+
+\begin{verbatim}
+data UserEntry
+\end{verbatim}
+
+A \tr{UserEntry} is a primitive of type \tr{struct passwd}.
+
+\begin{verbatim}
+data BaudRate = B0 | B50 | B75 | B110 | B134 | B150 | B200 | B300 | B600
+ | B1200 | B1800 | B2400 | B4800 | B9600 | B19200 | B38400
+ deriving (Eq, Show)
+
+type Channel = Int
+
+data ChannelOption = AppendOnWrite
+ | CloseOnExec
+ | NonBlockingRead
+
+data ControlCharacter = EndOfFile
+ | EndOfLine
+ | Erase
+ | Interrupt
+ | Kill
+ | Quit
+ | Suspend
+ | Start
+ | Stop
+
+type ErrorCode = Int
+
+type FileLock = (LockRequest, SeekMode, FileOffset, FileOffset)
+-- whence start length
+
+data FlowAction = SuspendOutput | RestartOutput | TransmitStop | TransmitStart
+
+data Handler = Default | Ignore | Catch (IO ())
+
+data LockRequest = ReadLock | WriteLock | Unlock
+ deriving (Eq, Show)
+
+data OpenMode = ReadOnly | WriteOnly | ReadWrite
+
+data PathVar = LinkLimit
+ | InputLineLimit
+ | InputQueueLimit
+ | FileNameLimit
+ | PathNameLimit
+ | PipeBufferLimit
+ | SetOwnerAndGroupIsRestricted
+ | FileNamesAreNotTruncated
+
+data QueueSelector = InputQueue | OutputQueue | BothQueues
+
+type Signal = Int
+
+data SysVar = ArgumentLimit
+ | ChildLimit
+ | ClockTick
+ | GroupLimit
+ | OpenFileLimit
+ | PosixVersion
+ | HasSavedIDs
+ | HasJobControl
+
+data TerminalMode = InterruptOnBreak -- BRKINT
+ | MapCRtoLF -- ICRNL
+ | IgnoreBreak -- IGNBRK
+ | IgnoreCR -- IGNCR
+ | IgnoreParityErrors -- IGNPAR
+ | MapLFtoCR -- INLCR
+ | CheckParity -- INPCK
+ | StripHighBit -- ISTRIP
+ | StartStopInput -- IXOFF
+ | StartStopOutput -- IXON
+ | MarkParityErrors -- PARMRK
+ | ProcessOutput -- OPOST
+ | LocalMode -- CLOCAL
+ | ReadEnable -- CREAD
+ | TwoStopBits -- CSTOPB
+ | HangupOnClose -- HUPCL
+ | EnableParity -- PARENB
+ | OddParity -- PARODD
+ | EnableEcho -- ECHO
+ | EchoErase -- ECHOE
+ | EchoKill -- ECHOK
+ | EchoLF -- ECHONL
+ | ProcessInput -- ICANON
+ | ExtendedFunctions -- IEXTEN
+ | KeyboardInterrupts -- ISIG
+ | NoFlushOnInterrupt -- NOFLSH
+ | BackgroundWriteInterrupt -- TOSTOP
+
+data TerminalState = Immediately | WhenDrained | WhenFlushed
+
+data ProcessStatus = Exited ExitCode
+ | Terminated Signal
+ | Stopped Signal
+ deriving (Eq, Show)
+\end{verbatim}
+
+\subsubsection{posix-process-env}{Posix Process Primitives}
+
+\begin{verbatim}
+forkProcess :: IO (Maybe ProcessID)
+\end{verbatim}
+
+\tr{forkProcess} calls \tr{fork}, returning
+\tr{Just pid} to the parent, where <var>pid</var> is the
+ProcessID of the child, and returning \tr{Nothing} to the
+child.
+
+\begin{verbatim}
+executeFile :: FilePath -- Command
+ -> Bool -- Search PATH?
+ -> [String] -- Arguments
+ -> Maybe [(String, String)] -- Environment
+ -> IO ()
+\end{verbatim}
+
+\tr{executeFile cmd args env} calls one of the
+\tr{execv*} family, depending on whether or not the current
+PATH is to be searched for the command, and whether or not an
+environment is provided to supersede the process's current
+environment. The basename (leading directory names suppressed) of
+the command is passed to \tr{execv*} as \tr{arg[0]};
+the argument list passed to \tr{executeFile} therefore begins
+with \tr{arg[1]}.
+
+\begin{verbatim}
+Search PATH? Supersede environ? Call
+~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ~~~~~~~
+False False execv
+False True execve
+True False execvp
+True True execvpe*
+\end{verbatim}
+
+Note that \tr{execvpe} is not provided by the POSIX standard, and must
+be written by hand. Care must be taken to ensure that the search path
+is extracted from the original environment, and not from the
+environment to be passed on to the new image.
+
+A successful \tr{executeFile} overlays the current process image with
+a new one, so it only returns on failure.
+\begin{verbatim}
+runProcess :: FilePath -- Command
+ -> [String] -- Arguments
+ -> Maybe [(String, String)] -- Environment (Nothing -> Inherited)
+ -> Maybe FilePath -- Working directory (Nothing -> inherited)
+ -> Maybe Handle -- stdin (Nothing -> inherited)
+ -> Maybe Handle -- stdout (Nothing -> inherited)
+ -> Maybe Handle -- stderr (Nothing -> inherited)
+ -> IO ()
+\end{verbatim}
+
+\tr{runProcess} is our candidate for the high-level OS-independent
+primitive.
+
+\tr{runProcess cmd args env wd inhdl outhdl errhdl} runs \tr{cmd}
+(searching the current \tr{PATH}) with arguments \tr{args}. If
+\tr{env} is \tr{Just pairs}, the command is executed with the
+environment specified by \tr{pairs} of variables and values;
+otherwise, the command is executed with the current environment. If
+\tr{wd} is \tr{Just dir}, the command is executed with working
+directory \tr{dir}; otherwise, the command is executed in the current
+working directory. If \tr{{in,out,err}hdl} is \tr{Just handle}, the
+command is executed with the \tr{Channel} for \tr{std{in,out,err}}
+attached to the specified \tr{handle}; otherwise, the \tr{Channel} for
+\tr{std{in,out,err}} is left unchanged.
+
+\begin{verbatim}
+getProcessStatus :: Bool -- Block?
+ -> Bool -- Stopped processes?
+ -> ProcessID
+ -> IO (Maybe ProcessStatus)
+\end{verbatim}
+
+\tr{getProcessStatus blk stopped pid} calls \tr{waitpid}, returning
+\tr{Just tc}, the \tr{ProcessStatus} for process \tr{pid} if it is
+available, \tr{Nothing} otherwise. If \tr{blk} is \tr{False}, then
+\tr{WNOHANG} is set in the options for \tr{waitpid}, otherwise not.
+If \tr{stopped} is \tr{True}, then \tr{WUNTRACED} is set in the
+options for \tr{waitpid}, otherwise not.
+
+\begin{verbatim}
+getGroupProcessStatus :: Bool -- Block?
+ -> Bool -- Stopped processes?
+ -> ProcessGroupID
+ -> IO (Maybe (ProcessID, ProcessStatus))
+\end{verbatim}
+
+\tr{getGroupProcessStatus blk stopped pgid} calls \tr{waitpid},
+returning \tr{Just (pid, tc)}, the \tr{ProcessID} and
+\tr{ProcessStatus} for any process in group \tr{pgid} if one is
+available, \tr{Nothing} otherwise. If \tr{blk} is \tr{False}, then
+\tr{WNOHANG} is set in the options for \tr{waitpid}, otherwise not.
+If \tr{stopped} is \tr{True}, then \tr{WUNTRACED} is set in the
+options for \tr{waitpid}, otherwise not.
+
+\begin{verbatim}
+getAnyProcessStatus :: Bool -- Block?
+ -> Bool -- Stopped processes?
+ -> IO (Maybe (ProcessID, ProcessStatus))
+\end{verbatim}
+
+\tr{getAnyProcessStatus blk stopped} calls \tr{waitpid}, returning
+\tr{Just (pid, tc)}, the \tr{ProcessID} and \tr{ProcessStatus} for any
+child process if one is available, \tr{Nothing} otherwise. If
+\tr{blk} is \tr{False}, then \tr{WNOHANG} is set in the options for
+\tr{waitpid}, otherwise not. If \tr{stopped} is \tr{True}, then
+\tr{WUNTRACED} is set in the options for \tr{waitpid}, otherwise not.
+
+\begin{verbatim}
+exitImmediately :: ExitCode -> IO ()
+\end{verbatim}
+
+\tr{exitImmediately status} calls \tr{_exit} to terminate the process
+with the indicated exit \tr{status}.
+The operation never returns.
+
+\begin{verbatim}
+getEnvironment :: IO [(String, String)]
+\end{verbatim}
+
+\tr{getEnvironment} parses the environment variable mapping provided by
+\tr{environ}, returning \tr{(variable, value)} pairs.
+The operation never fails.
+
+\begin{verbatim}
+setEnvironment :: [(String, String)] -> IO ()
+\end{verbatim}
+
+\tr{setEnvironment} replaces the process environment with the provided
+mapping of \tr{(variable, value)} pairs.
+
+\begin{verbatim}
+getEnvVar :: String -> IO String
+\end{verbatim}
+
+\tr{getEnvVar var} returns the value associated with variable \tr{var}
+in the current environment (identical functionality provided through
+standard Haskell library function @System.getEnv@).
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+The variable has no mapping in the current environment.
+\end{itemize}
+
+\begin{verbatim}
+setEnvVar :: String -> String -> IO ()
+\end{verbatim}
+
+\tr{setEnvVar var val} sets the value associated with variable \tr{var}
+in the current environment to be \tr{val}. Any previous mapping is
+superseded.
+
+\begin{verbatim}
+removeEnvVar :: String -> IO ()
+\end{verbatim}
+
+\tr{removeEnvVar var} removes any value associated with variable \tr{var}
+in the current environment. Deleting a variable for which there is no mapping
+does not generate an error.
+
+\begin{verbatim}
+nullSignal :: Signal
+nullSignal = 0
+
+backgroundRead, sigTTIN :: Signal
+backgroundWrite, sigTTOU :: Signal
+continueProcess, sigCONT :: Signal
+floatingPointException, sigFPE :: Signal
+illegalInstruction, sigILL :: Signal
+internalAbort, sigABRT :: Signal
+keyboardSignal, sigINT :: Signal
+keyboardStop, sigTSTP :: Signal
+keyboardTermination, sigQUIT :: Signal
+killProcess, sigKILL :: Signal
+lostConnection, sigHUP :: Signal
+openEndedPipe, sigPIPE :: Signal
+processStatusChanged, sigCHLD :: Signal
+realTimeAlarm, sigALRM :: Signal
+segmentationViolation, sigSEGV :: Signal
+softwareStop, sigSTOP :: Signal
+softwareTermination, sigTERM :: Signal
+userDefinedSignal1, sigUSR1 :: Signal
+userDefinedSignal2, sigUSR2 :: Signal
+
+signalProcess :: Signal -> ProcessID -> IO ()
+\end{verbatim}
+
+\tr{signalProcess int pid} calls \tr{kill} to signal
+process \tr{pid} with interrupt signal \tr{int}.
+
+\begin{verbatim}
+raiseSignal :: Signal -> IO ()
+\end{verbatim}
+
+\tr{raiseSignal int} calls \tr{kill} to signal the current process
+with interrupt signal \tr{int}.
+
+\begin{verbatim}
+signalProcessGroup :: Signal -> ProcessGroupID -> IO ()
+\end{verbatim}
+
+\tr{signalProcessGroup int pgid} calls \tr{kill} to signal
+all processes in group \tr{pgid} with interrupt signal \tr{int}.
+
+\begin{verbatim}
+setStoppedChildFlag :: Bool -> IO Bool
+\end{verbatim}
+
+\tr{setStoppedChildFlag bool} sets a flag which controls whether or
+not the \tr{NOCLDSTOP} option will be used the next time a signal
+handler is installed for \tr{SIGCHLD}. If \tr{bool} is \tr{True} (the
+default), \tr{NOCLDSTOP} will not be used; otherwise it will be. The
+operation never fails.
+
+\begin{verbatim}
+queryStoppedChildFlag :: IO Bool
+\end{verbatim}
+
+\tr{queryStoppedChildFlag} queries the flag which
+controls whether or not the \tr{NOCLDSTOP} option will be used
+the next time a signal handler is installed for \tr{SIGCHLD}.
+If \tr{NOCLDSTOP} will be used, it returns \tr{False};
+otherwise (the default) it returns \tr{True}.
+The operation never fails.
+
+\begin{verbatim}
+emptySignalSet :: SignalSet
+fullSignalSet :: SignalSet
+addSignal :: Signal -> SignalSet -> SignalSet
+deleteSignal :: Signal -> SignalSet -> SignalSet
+inSignalSet :: Signal -> SignalSet -> Bool
+
+installHandler :: Signal
+ -> Handler
+ -> Maybe SignalSet -- other signals to block
+ -> IO Handler -- old handler
+\end{verbatim}
+
+\tr{installHandler int handler iset} calls \tr{sigaction} to install
+an interrupt handler for signal \tr{int}. If \tr{handler} is
+\tr{Default}, \tr{SIG_DFL} is installed; if \tr{handler} is
+\tr{Ignore}, \tr{SIG_IGN} is installed; if \tr{handler} is \tr{Catch
+action}, a handler is installed which will invoke \tr{action} as a
+replacement for \tr{main}. If \tr{iset} is \tr{Just s}, then the
+\tr{sa_mask} of the \tr{sigaction} structure is set to \tr{s};
+otherwise it is cleared. The previously installed signal handler for
+\tr{int} is returned.
+
+\begin{verbatim}
+getSignalMask :: IO SignalSet
+\end{verbatim}
+
+\tr{getSignalMask} calls \tr{sigprocmask} to determine the
+set of interrupts which are currently being blocked.
+
+\begin{verbatim}
+setSignalMask :: SignalSet -> IO SignalSet
+\end{verbatim}
+
+\tr{setSignalMask mask} calls \tr{sigprocmask} with
+\tr{SIG_SETMASK} to block all interrupts in \tr{mask}. The
+previous set of blocked interrupts is returned.
+
+\begin{verbatim}
+blockSignals :: SignalSet -> IO SignalSet
+\end{verbatim}
+
+\tr{setSignalMask mask} calls \tr{sigprocmask} with
+\tr{SIG_BLOCK} to add all interrupts in \tr{mask} to the
+set of blocked interrupts. The previous set of blocked interrupts is returned.
+
+\begin{verbatim}
+unBlockSignals :: SignalSet -> IO SignalSet
+\end{verbatim}
+
+\tr{setSignalMask mask} calls \tr{sigprocmask} with
+\tr{SIG_UNBLOCK} to remove all interrupts in \tr{mask} from the
+set of blocked interrupts. The previous set of blocked interrupts is returned.
+
+\begin{verbatim}
+getPendingSignals :: IO SignalSet
+\end{verbatim}
+
+\tr{getPendingSignals} calls \tr{sigpending} to obtain
+the set of interrupts which have been received but are currently blocked.
+
+\begin{verbatim}
+awaitSignal :: Maybe SignalSet -> IO ()
+\end{verbatim}
+
+\tr{awaitSignal iset} suspends execution until an interrupt is received.
+If \tr{iset} is \tr{Just s}, \tr{awaitSignal} calls
+\tr{sigsuspend}, installing \tr{s} as the new signal mask before
+suspending execution; otherwise, it calls \tr{pause}. If successful,
+\tr{awaitSignal} does not return.
+
+\begin{verbatim}
+scheduleAlarm :: Int -> IO Int
+\end{verbatim}
+
+\tr{scheduleAlarm i} calls \tr{alarm} to schedule a real time
+alarm at least \tr{i} seconds in the future.
+
+\begin{verbatim}
+sleep :: Int -> IO ()
+\end{verbatim}
+
+\tr{sleep i} calls \tr{sleep} to suspend execution of the
+program until at least \tr{i} seconds have elapsed or a signal is
+received.
+
+\subsubsection[posix-proc-env]{Posix Process Environment}
+\index{Posix, process environment}
+
+\begin{verbatim}
+getProcessID :: IO ProcessID
+\end{verbatim}
+
+\tr{getProcessID} calls \tr{getpid} to obtain the \tr{ProcessID} for
+the current process.
+
+\begin{verbatim}
+getParentProcessID :: IO ProcessID
+\end{verbatim}
+
+\tr{getProcessID} calls \tr{getppid} to obtain the \tr{ProcessID} for
+the parent of the current process.
+
+\begin{verbatim}
+getRealUserID :: IO UserID
+\end{verbatim}
+
+\tr{getRealUserID} calls \tr{getuid} to obtain the real \tr{UserID}
+associated with the current process.
+
+\begin{verbatim}
+getEffectiveUserID :: IO UserID
+\end{verbatim}
+
+\tr{getRealUserID} calls \tr{geteuid} to obtain the effective
+\tr{UserID} associated with the current process.
+
+\begin{verbatim}
+setUserID :: UserID -> IO ()
+\end{verbatim}
+
+\tr{setUserID uid} calls \tr{setuid} to set the real, effective, and
+saved set-user-id associated with the current process to \tr{uid}.
+
+\begin{verbatim}
+getLoginName :: IO String
+\end{verbatim}
+
+\tr{getLoginName} calls \tr{getlogin} to obtain the login name
+associated with the current process.
+
+\begin{verbatim}
+getRealGroupID :: IO GroupID
+\end{verbatim}
+
+\tr{getRealGroupID} calls \tr{getgid} to obtain the real \tr{GroupID}
+associated with the current process.
+
+\begin{verbatim}
+getEffectiveGroupID :: IO GroupID
+\end{verbatim}
+
+\tr{getEffectiveGroupID} calls \tr{getegid} to obtain the effective
+\tr{GroupID} associated with the current process.
+
+\begin{verbatim}
+setGroupID :: GroupID -> IO ()
+\end{verbatim}
+
+\tr{setGroupID gid} calls \tr{setgid} to set the real, effective, and
+saved set-group-id associated with the current process to \tr{gid}.
+
+\begin{verbatim}
+getGroups :: IO [GroupID]
+\end{verbatim}
+
+\tr{getGroups} calls \tr{getgroups} to obtain the list of
+supplementary \tr{GroupID}s associated with the current process.
+
+\begin{verbatim}
+getEffectiveUserName :: IO String
+\end{verbatim}
+
+\tr{getEffectiveUserName} calls \tr{cuserid} to obtain a name
+associated with the effective \tr{UserID} of the process.
+
+\begin{verbatim}
+getProcessGroupID :: IO ProcessGroupID
+\end{verbatim}
+
+\tr{getProcessGroupID} calls \tr{getpgrp} to obtain the
+\tr{ProcessGroupID} for the current process.
+
+\begin{verbatim}
+createProcessGroup :: ProcessID -> IO ProcessGroupID
+\end{verbatim}
+
+\tr{createProcessGroup pid} calls \tr{setpgid} to make
+process \tr{pid} a new process group leader.
+
+\begin{verbatim}
+joinProcessGroup :: ProcessGroupID -> IO ProcessGroupID
+\end{verbatim}
+
+\tr{joinProcessGroup pgid} calls \tr{setpgid} to set the
+\tr{ProcessGroupID} of the current process to \tr{pgid}.
+
+\begin{verbatim}
+setProcessGroupID :: ProcessID -> ProcessGroupID -> IO ()
+\end{verbatim}
+
+\tr{setProcessGroupID pid pgid} calls \tr{setpgid} to set the
+\tr{ProcessGroupID} for process \tr{pid} to \tr{pgid}.
+
+\begin{verbatim}
+createSession :: IO ProcessGroupID
+\end{verbatim}
+
+\tr{createSession} calls \tr{setsid} to create a new session
+with the current process as session leader.
+
+\begin{verbatim}
+systemName :: SystemID -> String
+nodeName :: SystemID -> String
+release :: SystemID -> String
+version :: SystemID -> String
+machine :: SystemID -> String
+
+getSystemID :: IO SystemID
+\end{verbatim}
+
+\tr{getSystemID} calls \tr{uname} to obtain information
+about the current operating system.
+
+\begin{verbatim}
+> epochTime :: IO EpochTime
+\end{verbatim}
+
+\tr{epochTime} calls \tr{time} to obtain the number of
+seconds that have elapsed since the epoch (Jan 01 00:00:00 GMT 1970).
+
+\begin{verbatim}
+elapsedTime :: ProcessTimes -> ClockTick
+userTime :: ProcessTimes -> ClockTick
+systemTime :: ProcessTimes -> ClockTick
+childUserTime :: ProcessTimes -> ClockTick
+childSystemTime :: ProcessTimes -> ClockTick
+
+getProcessTimes :: IO ProcessTimes
+\end{verbatim}
+
+\tr{getProcessTimes} calls \tr{times} to obtain time-accounting
+information for the current process and its children.
+
+\begin{verbatim}
+getControllingTerminalName :: IO FilePath
+\end{verbatim}
+
+\tr{getControllingTerminalName} calls \tr{ctermid} to obtain
+a name associated with the controlling terminal for the process. If a
+controlling terminal exists,
+\tr{getControllingTerminalName} returns the name of the
+controlling terminal.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+There is no controlling terminal, or its name cannot be determined.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+\begin{verbatim}
+getTerminalName :: Channel -> IO FilePath
+\end{verbatim}
+
+\tr{getTerminalName fd} calls \tr{ttyname} to obtain a name associated
+with the terminal for \tr{Channel} \tr{fd}. If \tr{fd} is associated
+with a terminal, \tr{getTerminalName} returns the name of the
+terminal.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{InappropriateType}]
+The channel is not associated with a terminal.
+\item[\tr{NoSuchThing}]
+The channel is associated with a terminal, but it has no name.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+\begin{verbatim}
+queryTerminal :: Channel -> IO Bool
+\end{verbatim}
+
+\tr{queryTerminal fd} calls \tr{isatty} to determine whether or
+not \tr{Channel} \tr{fd} is associated with a terminal.
+
+\begin{verbatim}
+getSysVar :: SysVar -> IO Limit
+\end{verbatim}
+
+\tr{getSysVar var} calls \tr{sysconf} to obtain the
+dynamic value of the requested configurable system limit or option.
+For defined system limits, \tr{getSysVar} returns the associated
+value. For defined system options, the result of \tr{getSysVar}
+is undefined, but not failure.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+The requested system limit or option is undefined.
+\end{itemize}
+
+\subsubsection[posix-files-dir]{Files and Directories}
+\index{Posix, files and directories}
+
+\begin{verbatim}
+openDirStream :: FilePath -> IO DirStream
+\end{verbatim}
+
+\tr{openDirStream dir} calls \tr{opendir} to obtain a
+directory stream for \tr{dir}.
+
+\begin{verbatim}
+readDirStream :: DirStream -> IO String
+\end{verbatim}
+
+\tr{readDirStream dp} calls \tr{readdir} to obtain the
+next directory entry (\tr{struct dirent}) for the open directory
+stream \tr{dp}, and returns the \tr{d_name} member of that
+structure.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{EOF}]
+End of file has been reached.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+\begin{verbatim}
+rewindDirStream :: DirStream -> IO ()
+\end{verbatim}
+
+\tr{rewindDirStream dp} calls \tr{rewinddir} to reposition
+the directory stream \tr{dp} at the beginning of the directory.
+
+\begin{verbatim}
+closeDirStream :: DirStream -> IO ()
+\end{verbatim}
+
+\tr{closeDirStream dp} calls \tr{closedir} to close
+the directory stream \tr{dp}.
+
+\begin{verbatim}
+getWorkingDirectory :: IO FilePath
+\end{verbatim}
+
+\tr{getWorkingDirectory} calls \tr{getcwd} to obtain the name
+of the current working directory.
+
+\begin{verbatim}
+changeWorkingDirectory :: FilePath -> IO ()
+\end{verbatim}
+
+\tr{changeWorkingDirectory dir} calls \tr{chdir} to change
+the current working directory to \tr{dir}.
+
+\begin{verbatim}
+nullFileMode :: FileMode -- ---------
+ownerReadMode :: FileMode -- r--------
+ownerWriteMode :: FileMode -- -w-------
+ownerExecuteMode :: FileMode -- --x------
+groupReadMode :: FileMode -- ---r-----
+groupWriteMode :: FileMode -- ----w----
+groupExecuteMode :: FileMode -- -----x---
+otherReadMode :: FileMode -- ------r--
+otherWriteMode :: FileMode -- -------w-
+otherExecuteMode :: FileMode -- --------x
+setUserIDMode :: FileMode -- --S------
+setGroupIDMode :: FileMode -- -----S---
+
+stdFileMode :: FileMode -- rw-rw-rw-
+
+ownerModes :: FileMode -- rwx------
+groupModes :: FileMode -- ---rwx---
+otherModes :: FileMode -- ------rwx
+accessModes :: FileMode -- rwxrwxrwx
+
+unionFileModes :: FileMode -> FileMode -> FileMode
+intersectFileModes :: FileMode -> FileMode -> FileMode
+
+stdInput :: Channel
+stdInput = 0
+
+stdOutput :: Channel
+stdOutput = 1
+
+stdError :: Channel
+stdError = 2
+
+openChannel :: FilePath
+ -> OpenMode
+ -> Maybe FileMode -- Just x => O_CREAT, Nothing => must exist
+ -> Bool -- O_APPEND
+ -> Bool -- O_EXCL
+ -> Bool -- O_NOCTTY
+ -> Bool -- O_NONBLOCK
+ -> Bool -- O_TRUNC
+ -> IO Channel
+\end{verbatim}
+
+\tr{openChannel path acc mode app excl noctty nonblock trunc} calls
+\tr{open} to obtain a \tr{Channel} for the file \tr{path} with access
+mode \tr{acc}. If \tr{mode} is \tr{Just m}, the \tr{O_CREAT} flag is
+set and the file's permissions will be based on \tr{m} if it does not
+already exist; otherwise, the \tr{O_CREAT} flag is not set. The
+arguments \tr{app}, \tr{excl}, \tr{noctty}, \tr{nonblock}, and
+\tr{trunc} control whether or not the flags \tr{O_APPEND},
+\tr{O_EXCL}, \tr{O_NOCTTY}, \tr{O_NONBLOCK}, and \tr{O_TRUNC} are set,
+respectively.
+
+\begin{verbatim}
+createFile :: FilePath -> FileMode -> IO Channel
+\end{verbatim}
+
+\tr{createFile path mode} calls \tr{creat} to obtain a \tr{Channel}
+for file \tr{path}, which will be created with permissions based on
+\tr{mode} if it does not already exist.
+
+\begin{verbatim}
+setFileCreationMask :: FileMode -> IO FileMode
+\end{verbatim}
+
+\tr{setFileCreationMask mode} calls \tr{umask} to set
+the process's file creation mask to \tr{mode}. The previous file
+creation mask is returned.
+
+\begin{verbatim}
+createLink :: FilePath -> FilePath -> IO ()
+\end{verbatim}
+
+\tr{createLink old new} calls \tr{link} to create a
+new path, \tr{new}, linked to an existing file, \tr{old}.
+\begin{verbatim}
+createDirectory :: FilePath -> FileMode -> IO ()
+\end{verbatim}
+
+\tr{createDirectory dir mode} calls \tr{mkdir} to
+create a new directory, \tr{dir}, with permissions based on
+\tr{mode}.
+
+\begin{verbatim}
+createNamedPipe :: FilePath -> FileMode -> IO ()
+\end{verbatim}
+
+\tr{createNamedPipe fifo mode} calls \tr{mkfifo} to
+create a new named pipe, \tr{fifo}, with permissions based on
+\tr{mode}.
+
+\begin{verbatim}
+removeLink :: FilePath -> IO ()
+\end{verbatim}
+
+\tr{removeLink path} calls \tr{unlink} to remove the link
+named \tr{path}.
+
+\begin{verbatim}
+removeDirectory :: FilePath -> IO ()
+\end{verbatim}
+
+\tr{removeDirectory dir} calls \tr{rmdir} to remove the
+directory named \tr{dir}.
+
+\begin{verbatim}
+rename :: FilePath -> FilePath -> IO ()
+\end{verbatim}
+
+\tr{rename old new} calls \tr{rename} to rename a
+file or directory from \tr{old} to \tr{new}.
+
+\begin{verbatim}
+fileMode :: FileStatus -> FileMode
+
+fileID :: FileStatus -> FileID
+deviceID :: FileStatus -> DeviceID
+
+linkCount :: FileStatus -> LinkCount
+
+fileOwner :: FileStatus -> UserID
+fileGroup :: FileStatus -> GroupID
+fileSize :: FileStatus -> FileOffset
+
+accessTime :: FileStatus -> EpochTime
+modificationTime :: FileStatus -> EpochTime
+statusChangeTime :: FileStatus -> EpochTime
+
+isDirectory :: FileStatus -> Bool
+isCharacterDevice :: FileStatus -> Bool
+isBlockDevice :: FileStatus -> Bool
+isRegularFile :: FileStatus -> Bool
+isNamedPipe :: FileStatus -> Bool
+
+getFileStatus :: FilePath -> IO FileStatus
+\end{verbatim}
+
+\tr{getFileStatus path} calls \tr{stat} to get the
+\tr{FileStatus} information for the file \tr{path}.
+
+\begin{verbatim}
+getChannelStatus :: Channel -> IO FileStatus
+\end{verbatim}
+
+\tr{getChannelStatus fd} calls \tr{fstat} to get the
+\tr{FileStatus} information for the file associated with
+\tr{Channel} \tr{fd}.
+
+\begin{verbatim}
+queryAccess :: FilePath -> Bool -> Bool -> Bool -> IO Bool
+\end{verbatim}
+
+\tr{queryAccess path r w x} calls \tr{access} to test the access
+permissions for file \tr{path}. The three arguments, \tr{r}, \tr{w},
+and \tr{x} control whether or not \tr{access} is called with
+\tr{R_OK}, \tr{W_OK}, and \tr{X_OK} respectively.
+
+\begin{verbatim}
+queryFile :: FilePath -> IO Bool
+\end{verbatim}
+
+\tr{queryFile path} calls \tr{access} with \tr{F_OK} to test for the
+existence for file \tr{path}.
+
+\begin{verbatim}
+setFileMode :: FilePath -> FileMode -> IO ()
+\end{verbatim}
+
+\tr{setFileMode path mode} calls \tr{chmod} to set the
+permission bits associated with file \tr{path} to \tr{mode}.
+
+\begin{verbatim}
+setOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()
+\end{verbatim}
+
+\tr{setOwnerAndGroup path uid gid} calls \tr{chown} to
+set the \tr{UserID} and \tr{GroupID} associated with file
+\tr{path} to \tr{uid} and \tr{gid}, respectively.
+
+\begin{verbatim}
+setFileTimes :: FilePath -> EpochTime -> EpochTime -> IO ()
+\end{verbatim}
+
+\tr{setFileTimes path atime mtime} calls \tr{utime} to
+set the access and modification times associated with file
+\tr{path} to \tr{atime} and \tr{mtime}, respectively.
+
+\begin{verbatim}
+touchFile :: FilePath -> IO ()
+\end{verbatim}
+
+\tr{touchFile path} calls \tr{utime} to
+set the access and modification times associated with file
+\tr{path} to the current time.
+
+\begin{verbatim}
+getPathVar :: PathVar -> FilePath -> IO Limit
+\end{verbatim}
+
+\tr{getPathVar var path} calls \tr{pathconf} to obtain the
+dynamic value of the requested configurable file limit or option associated
+with file or directory \tr{path}. For
+defined file limits, \tr{getPathVar} returns the associated
+value. For defined file options, the result of \tr{getPathVar}
+is undefined, but not failure.
+The operation may fail with:
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+The requested file limit or option is undefined.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+
+\begin{verbatim}
+getChannelVar :: PathVar -> Channel -> IO Limit
+\end{verbatim}
+
+\tr{getChannelVar var fd} calls \tr{fpathconf} to obtain the
+dynamic value of the requested configurable file limit or option associated
+with the file or directory attached to the open channel \tr{fd}.
+For defined file limits, \tr{getChannelVar} returns the associated
+value. For defined file options, the result of \tr{getChannelVar}
+is undefined, but not failure.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+The requested file limit or option is undefined.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+\subsubsection[posix-input-output]{Posix Input and Output Primitives}
+\index{Posix, input/output}
+
+\begin{verbatim}
+createPipe :: IO (Channel, Channel)
+\end{verbatim}
+
+\tr{createPipe} calls \tr{pipe} to create a pipe and returns a pair of
+\tr{Channels}, the first for writing and the second for reading.
+
+\begin{verbatim}
+dupChannel :: Channel -> IO Channel
+\end{verbatim}
+
+\tr{dupChannel fd} calls \tr{dup} to duplicate \tr{Channel} \tr{fd} to
+another \tr{Channel}.
+
+\begin{verbatim}
+dupChannelTo :: Channel -> Channel -> IO ()
+\end{verbatim}
+
+\tr{dupChannelTo src dst} calls \tr{dup2} to duplicate \tr{Channel}
+\tr{src} to \tr{Channel} \tr{dst}.
+
+\begin{verbatim}
+closeChannel :: Channel -> IO ()
+\end{verbatim}
+
+\tr{closeChannel fd} calls \tr{close} to close \tr{Channel} \tr{fd}.
+
+\begin{verbatim}
+readChannel :: Channel -> ByteCount -> IO (String, ByteCount)
+\end{verbatim}
+
+\tr{readChannel fd nbytes} calls \tr{read} to read at most \tr{nbytes}
+bytes from \tr{Channel} \tr{fd}, and returns the result as a string
+paired with the number of bytes actually read.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{EOF}]
+End of file has been reached.
+\item[\tr{SystemError}]
+Various other causes.
+\end{itemize}
+
+\begin{verbatim}
+writeChannel :: Channel -> String -> IO ByteCount
+\end{verbatim}
+
+\tr{writeChannel fd s} calls \tr{write} to write
+the string \tr{s} to \tr{Channel} \tr{fd} as a
+contiguous sequence of bytes. It returns the number of bytes successfully
+written.
+
+\begin{verbatim}
+queryChannelOption :: ChannelOption -> Channel -> IO Bool
+\end{verbatim}
+
+\tr{getChannelOption opt fd} calls \tr{fcntl} to determine whether or
+not the flag associated with \tr{ChannelOption} \tr{opt} is set for
+\tr{Channel} \tr{fd}.
+
+\begin{verbatim}
+setChannelOption :: ChannelOption -> Bool -> Channel -> IO ()
+\end{verbatim}
+
+\tr{setChannelOption opt val fd} calls \tr{fcntl} to set the flag
+associated with \tr{ChannelOption} \tr{opt} on \tr{Channel} \tr{fd} to
+\tr{val}.
+
+\begin{verbatim}
+getLock :: Channel -> FileLock -> IO (Maybe (ProcessID, FileLock))
+\end{verbatim}
+
+\tr{getLock fd lock} calls \tr{fcntl} to get the first \tr{FileLock}
+for \tr{Channel} \tr{fd} which blocks the \tr{FileLock} \tr{lock}. If
+no such \tr{FileLock} exists, \tr{getLock} returns \tr{Nothing}.
+Otherwise, it returns \tr{Just (pid, block)}, where \tr{block} is the
+blocking \tr{FileLock} and \tr{pid} is the \tr{ProcessID} of the
+process holding the blocking \tr{FileLock}.
+
+
+\begin{verbatim}
+setLock :: Channel -> FileLock -> IO ()
+\end{verbatim}
+
+\tr{setLock fd lock} calls \tr{fcntl} with \tr{F_SETLK} to set or
+clear a lock segment for \tr{Channel} \tr{fd} as indicated by the
+\tr{FileLock} \tr{lock}. \tr{setLock} does not block, but fails with
+\tr{SystemError} if the request cannot be satisfied immediately.
+
+\begin{verbatim}
+waitToSetLock :: Channel -> FileLock -> IO ()
+\end{verbatim}
+
+\tr{waitToSetLock fd lock} calls \tr{fcntl} with \tr{F_SETLKW} to set
+or clear a lock segment for \tr{Channel} \tr{fd} as indicated by the
+\tr{FileLock} \tr{lock}. If the request cannot be satisfied
+immediately, \tr{waitToSetLock} blocks until the request can be
+satisfied.
+
+
+\begin{verbatim}
+seekChannel :: Channel -> SeekMode -> FileOffset -> IO FileOffset
+\end{verbatim}
+
+\tr{seekChannel fd whence offset} calls \tr{lseek} to position the
+\tr{Channel} at the given \tr{offset} from the starting location
+indicated by \tr{whence}. It returns the resulting offset from the
+start of the file in bytes.
+
+\subsubsection[posix-device-class]{Posix, Device- and Class-Specific Functions}
+\index{Posix, device and class-specific functions}
+
+\begin{verbatim}
+terminalMode :: TerminalMode -> TerminalAttributes -> Bool
+withMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes
+withoutMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes
+
+bitsPerByte :: TerminalAttributes -> Int
+withBits :: TerminalAttributes -> Int -> TerminalAttributes
+
+controlChar :: TerminalAttributes -> ControlCharacter -> Maybe Char
+withCC :: TerminalAttributes
+ -> (ControlCharacter, Char)
+ -> TerminalAttributes
+withoutCC :: TerminalAttributes
+ -> ControlCharacter
+ -> TerminalAttributes
+
+inputTime :: TerminalAttributes -> Int
+withTime :: TerminalAttributes -> Int -> TerminalAttributes
+
+minInput :: TerminalAttributes -> Int
+withMinInput :: TerminalAttributes -> Int -> TerminalAttributes
+
+inputSpeed :: TerminalAttributes -> BaudRate
+withInputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes
+
+outputSpeed :: TerminalAttributes -> BaudRate
+withOutputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes
+
+getTerminalAttributes :: Channel -> IO TerminalAttributes
+\end{verbatim}
+
+\tr{getTerminalAttributes fd} calls \tr{tcgetattr} to obtain
+the \tr{TerminalAttributes} associated with \tr{Channel}
+\tr{fd}.
+
+\begin{verbatim}
+setTerminalAttributes :: Channel
+ -> TerminalAttributes
+ -> TerminalState
+ -> IO ()
+\end{verbatim}
+
+\tr{setTerminalAttributes fd attr ts} calls \tr{tcsetattr} to change
+the \tr{TerminalAttributes} associated with \tr{Channel} \tr{fd} to
+\tr{attr}, when the terminal is in the state indicated by \tr{ts}.
+
+\begin{verbatim}
+sendBreak :: Channel -> Int -> IO ()
+\end{verbatim}
+
+\tr{sendBreak fd duration} calls \tr{tcsendbreak} to transmit a
+continuous stream of zero-valued bits on \tr{Channel} \tr{fd} for the
+specified implementation-dependent \tr{duration}.
+
+\begin{verbatim}
+drainOutput :: Channel -> IO ()
+\end{verbatim}
+
+\tr{drainOutput fd} calls \tr{tcdrain} to block until all output
+written to \tr{Channel} \tr{fd} has been transmitted.
+
+\begin{verbatim}
+discardData :: Channel -> QueueSelector -> IO ()
+\end{verbatim}
+
+\tr{discardData fd queues} calls \tr{tcflush} to discard
+pending input and/or output for \tr{Channel} \tr{fd},
+as indicated by the \tr{QueueSelector} \tr{queues}.
+
+\begin{verbatim}
+controlFlow :: Channel -> FlowAction -> IO ()
+\end{verbatim}
+
+\tr{controlFlow fd action} calls \tr{tcflow} to control the
+flow of data on \tr{Channel} \tr{fd}, as indicated by
+\tr{action}.
+
+\begin{verbatim}
+getTerminalProcessGroupID :: Channel -> IO ProcessGroupID
+\end{verbatim}
+
+\tr{getTerminalProcessGroupID fd} calls \tr{tcgetpgrp} to
+obtain the \tr{ProcessGroupID} of the foreground process group
+associated with the terminal attached to \tr{Channel}
+\tr{fd}.
+
+\begin{verbatim}
+setTerminalProcessGroupID :: Channel -> ProcessGroupID -> IO ()
+\end{verbatim}
+
+\tr{setTerminalProcessGroupID fd pgid} calls \tr{tcsetpgrp} to
+set the \tr{ProcessGroupID} of the foreground process group
+associated with the terminal attached to \tr{Channel}
+\tr{fd} to \tr{pgid}.
+
+\subsubsection[posix-system-db]{Posix System Databases}
+\index{Posix, system databases}
+
+\begin{verbatim}
+groupName :: GroupEntry -> String
+groupID :: GroupEntry -> GroupID
+groupMembers :: GroupEntry -> [String]
+
+getGroupEntryForID :: GroupID -> IO GroupEntry
+\end{verbatim}
+
+\tr{getGroupEntryForID gid} calls \tr{getgrgid} to obtain
+the \tr{GroupEntry} information associated with \tr{GroupID}
+\tr{gid}.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+There is no group entry for the GroupID.
+\end{itemize}
+
+\begin{verbatim}
+getGroupEntryForName :: String -> IO GroupEntry
+\end{verbatim}
+
+\tr{getGroupEntryForName name} calls \tr{getgrnam} to obtain
+the \tr{GroupEntry} information associated with the group called
+\tr{name}.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+There is no group entry for the name.
+\end{itemize}
+
+\begin{verbatim}
+userName :: UserEntry -> String
+userID :: UserEntry -> UserID
+userGroupID :: UserEntry -> GroupID
+homeDirectory :: UserEntry -> String
+userShell :: UserEntry -> String
+
+getUserEntryForID :: UserID -> IO UserEntry
+\end{verbatim}
+
+\tr{getUserEntryForID gid} calls \tr{getpwuid} to obtain
+the \tr{UserEntry} information associated with \tr{UserID}
+\tr{uid}.
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+There is no user entry for the UserID.
+\end{itemize}
+
+\begin{verbatim}
+getUserEntryForName :: String -> IO UserEntry
+\end{verbatim}
+
+\tr{getUserEntryForName name} calls \tr{getpwnam} to obtain
+the \tr{UserEntry} information associated with the user login
+\tr{name}.
+
+The operation may fail with:
+
+\begin{itemize}
+\item[\tr{NoSuchThing}]
+There is no user entry for the name.
+\end{itemize}
+
+\subsubsection[posix-errors]{POSIX Errors}
+\index{Posix, errors}
+
+\begin{verbatim}
+getErrorCode :: IO ErrorCode
+\end{verbatim}
+
+\tr{getErrorCode} returns the current value of the external
+variable \tr{errno}. It never fails.
+
+\begin{verbatim}
+setErrorCode :: ErrorCode -> IO ()
+\end{verbatim}
+
+\tr{setErrorCode err} sets the external
+variable \tr{errno} to \tr{err}. It never fails.
+
+\begin{verbatim}
+noError :: ErrorCode
+noError = 0
+
+argumentListTooLong, e2BIG :: ErrorCode
+badChannel, eBADF :: ErrorCode
+brokenPipe, ePIPE :: ErrorCode
+directoryNotEmpty, eNOTEMPTY :: ErrorCode
+execFormatError, eNOEXEC :: ErrorCode
+fileAlreadyExists, eEXIST :: ErrorCode
+fileTooLarge, eFBIG :: ErrorCode
+filenameTooLong, eNAMETOOLONG :: ErrorCode
+improperLink, eXDEV :: ErrorCode
+inappropriateIOControlOperation, eNOTTY :: ErrorCode
+inputOutputError, eIO :: ErrorCode
+interruptedOperation, eINTR :: ErrorCode
+invalidArgument, eINVAL :: ErrorCode
+invalidSeek, eSPIPE :: ErrorCode
+isADirectory, eISDIR :: ErrorCode
+noChildProcess, eCHILD :: ErrorCode
+noLocksAvailable, eNOLCK :: ErrorCode
+noSpaceLeftOnDevice, eNOSPC :: ErrorCode
+noSuchOperationOnDevice, eNODEV :: ErrorCode
+noSuchDeviceOrAddress, eNXIO :: ErrorCode
+noSuchFileOrDirectory, eNOENT :: ErrorCode
+noSuchProcess, eSRCH :: ErrorCode
+notADirectory, eNOTDIR :: ErrorCode
+notEnoughMemory, eNOMEM :: ErrorCode
+operationNotImplemented, eNOSYS :: ErrorCode
+operationNotPermitted, ePERM :: ErrorCode
+permissionDenied, eACCES :: ErrorCode
+readOnlyFileSystem, eROFS :: ErrorCode
+resourceBusy, eBUSY :: ErrorCode
+resourceDeadlockAvoided, eDEADLK :: ErrorCode
+resourceTemporarilyUnavailable, eAGAIN :: ErrorCode
+tooManyLinks, eMLINK :: ErrorCode
+tooManyOpenFiles, eMFILE :: ErrorCode
+tooManyOpenFilesInSystem, eNFILE :: ErrorCode
+
+\end{verbatim}
+
+%************************************************************************
+%* *
+\subsection[HBC-library]{The HBC system library}
+\index{HBC system library}
+\index{system library, HBC}
+%* *
+%************************************************************************
+
+This documentation is stolen directly from the HBC distribution. The
+modules that GHC does not support (because they require HBC-specific
+extensions) are omitted.
+
+\begin{description}
+\item[\tr{Either}:]
+\index{Either module (HBC library)}%
+A binary sum data type:
+\begin{verbatim}
+data Either a b = Left a | Right b
+\end{verbatim}
+The constructor \tr{Left} is typically used for errors; it can be
+renamed to \tr{Wrong} on import.
+
+\item[\tr{Maybe}:]
+\index{Maybe module (HBC library)}%
+A type for failure or success:
+\begin{verbatim}
+data Maybe a = Nothing | Just a
+thenM :: Maybe a -> (a -> Maybe b) -> Maybe b
+ -- apply a function that may fail
+\end{verbatim}
+
+\item[\tr{Option}:]
+\index{Option module (HBC library)}%
+An alias for \tr{Maybe}:
+\begin{verbatim}
+data Option a = None | Some a
+thenO :: Option a -> (a -> Option b) -> Option b
+\end{verbatim}
+
+\item[\tr{ListUtil}:]
+\index{ListUtil module (HBC library)}%
+Various useful functions involving lists that are missing from the
+\tr{Prelude}:
+\begin{verbatim}
+assoc :: (Eq c) => (a -> b) -> b -> [(c, a)] -> c -> b
+ -- assoc f d l k looks for k in the association list l, if it
+ -- is found f is applied to the value, otherwise d is returned.
+concatMap :: (a -> [b]) -> [a] -> [b]
+ -- flattening map (LML's concmap)
+unfoldr :: (a -> (b, a)) -> (a -> Bool) -> a -> [b]
+ -- unfoldr f p x repeatedly applies f to x until (p x) holds.
+ -- (f x) should give a list element and a new x.
+mapAccuml :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
+ -- mapAccuml f s l maps f over l, but also threads the state s
+ -- through (LML's mapstate).
+union :: (Eq a) => [a] -> [a] -> [a]
+ -- union of two lists
+intersection :: (Eq a) => [a] -> [a] -> [a]
+ -- intersection of two lists
+chopList :: ([a] -> (b, [a])) -> [a] -> [b]
+ -- LMLs choplist
+assocDef :: (Eq a) => [(a, b)] -> b -> a -> b
+ -- LMLs assocdef
+lookup :: (Eq a) => [(a, b)] -> a -> Option b
+ -- lookup l k looks for the key k in the association list l
+ -- and returns an optional value
+tails :: [a] -> [[a]]
+ -- return all the tails of a list
+rept :: (Integral a) => a -> b -> [b]
+ -- repeat a value a number of times
+groupEq :: (a->a->Bool) -> [a] -> [[a]]
+ -- group list elements according to an equality predicate
+group :: (Eq a) => [a] -> [[a]]
+ -- group according to} ==
+readListLazily :: (Text a) => String -> [a]
+ -- read a list in a lazy fashion
+\end{verbatim}
+
+\item[\tr{Pretty}:]
+\index{Pretty module (HBC library)}%
+John Hughes's pretty printing library.
+\begin{verbatim}
+type Context = (Bool, Int, Int, Int)
+type IText = Context -> [String]
+text :: String -> IText -- just text
+(~.) :: IText -> IText -> IText -- horizontal composition
+(^.) :: IText -> IText -> IText -- vertical composition
+separate :: [IText] -> IText -- separate by spaces
+nest :: Int -> IText -> IText -- indent
+pretty :: Int -> Int -> IText -> String -- format it
+\end{verbatim}
+
+\item[\tr{QSort}:]
+\index{QSort module (HBC library)}%
+A sort function using quicksort.
+\begin{verbatim}
+sortLe :: (a -> a -> Bool) -> [a] -> [a]
+ -- sort le l sorts l with le as less than predicate
+sort :: (Ord a) => [a] -> [a]
+ -- sort l sorts l using the Ord class
+\end{verbatim}
+
+\item[\tr{Random}:]
+\index{Random module (HBC library)}%
+Random numbers.
+\begin{verbatim}
+randomInts :: Int -> Int -> [Int]
+ -- given two seeds gives a list of random Int
+randomDoubles :: Int -> Int -> [Double]
+ -- random Double with uniform distribution in (0,1)
+normalRandomDoubles :: Int -> Int -> [Double]
+ -- random Double with normal distribution, mean 0, variance 1
+\end{verbatim}
+
+\item[\tr{Trace}:]
+Simple tracing. (Note: This comes with GHC anyway.)
+\begin{verbatim}
+trace :: String -> a -> a -- trace x y prints x and returns y
+\end{verbatim}
+
+\item[\tr{Miranda}:]
+\index{Miranda module (HBC library)}%
+Functions found in the Miranda library.
+(Note: Miranda is a registered trade mark of Research Software Ltd.)
+
+\item[\tr{Word}:]
+\index{Word module (HBC library)}
+Bit manipulation. (GHC doesn't implement absolutely all of this.
+And don't count on @Word@ being 32 bits on a Alpha...)
+\begin{verbatim}
+class Bits a where
+ bitAnd :: a -> a -> a -- bitwise and
+ bitOr :: a -> a -> a -- bitwise or
+ bitXor :: a -> a -> a -- bitwise xor
+ bitCompl :: a -> a -- bitwise negation
+ bitRsh :: a -> Int -> a -- bitwise right shift
+ bitLsh :: a -> Int -> a -- bitwise left shift
+ bitSwap :: a -> a -- swap word halves
+ bit0 :: a -- word with least significant bit set
+ bitSize :: a -> Int -- number of bits in a word
+
+data Byte -- 8 bit quantity
+data Short -- 16 bit quantity
+data Word -- 32 bit quantity
+
+instance Bits Byte, Bits Short, Bits Word
+instance Eq Byte, Eq Short, Eq Word
+instance Ord Byte, Ord Short, Ord Word
+instance Text Byte, Text Short, Text Word
+instance Num Byte, Num Short, Num Word
+wordToShorts :: Word -> [Short] -- convert a Word to two Short
+wordToBytes :: Word -> [Byte] -- convert a Word to four Byte
+bytesToString :: [Byte] -> String -- convert a list of Byte to a String (bit by bit)
+wordToInt :: Word -> Int -- convert a Word to Int
+shortToInt :: Short -> Int -- convert a Short to Int
+byteToInt :: Byte -> Int -- convert a Byte to Int
+\end{verbatim}
+
+\item[\tr{Time}:]
+\index{Time module (HBC library)}%
+Manipulate time values (a Double with seconds since 1970).
+\begin{verbatim}
+-- year mon day hour min sec dec-sec weekday
+data Time = Time Int Int Int Int Int Int Double Int
+dblToTime :: Double -> Time -- convert a Double to a Time
+timeToDbl :: Time -> Double -- convert a Time to a Double
+timeToString :: Time -> String -- convert a Time to a readable String
+\end{verbatim}
+
+\item[\tr{Hash}:]
+\index{Hash module (HBC library)}%
+Hashing functions.
+\begin{verbatim}
+class Hashable a where
+ hash :: a -> Int -- hash a value, return an Int
+-- instances for all Prelude types
+hashToMax :: (Hashable a) => Int -> a -> Int -- hash into interval [0..x-1]
+\end{verbatim}
+
+\item[\tr{NameSupply}:]
+\index{NameSupply module (HBC library)}%
+Functions to generate unique names (Int).
+\begin{verbatim}
+type Name = Int
+initialNameSupply :: NameSupply
+ -- The initial name supply (may be different every
+ -- time the program is run.
+splitNameSupply :: NameSupply -> (NameSupply,NameSupply)
+ -- split the namesupply into two
+getName :: NameSupply -> Name
+ -- get the name associated with a name supply
+\end{verbatim}
+
+\item[\tr{Parse}:]
+\index{Parse module (HBC library)}%
+Higher order functions to build parsers. With a little care these
+combinators can be used to build efficient parsers with good error
+messages.
+\begin{verbatim}
+infixr 8 +.+ , ..+ , +..
+infix 6 `act` , >>> , `into` , .>
+infixr 4 ||| , ||! , |!!
+data ParseResult a b
+type Parser a b = a -> Int -> ParseResult a b
+(|||) :: Parser a b -> Parser a b -> Parser a b
+ -- Alternative
+(||!) :: Parser a b -> Parser a b -> Parser a b
+ -- Alternative, but with committed choice
+(|!!) :: Parser a b -> Parser a b -> Parser a b
+ -- Alternative, but with committed choice
+(+.+) :: Parser a b -> Parser a c -> Parser a (b,c)
+ -- Sequence
+(..+) :: Parser a b -> Parser a c -> Parser a c
+ -- Sequence, throw away first part
+(+..) :: Parser a b -> Parser a c -> Parser a b
+ -- Sequence, throw away second part
+act :: Parser a b -> (b->c) -> Parser a c
+ -- Action
+(>>>) :: Parser a (b,c) -> (b->c->d) -> Parser a d
+ -- Action on two items
+(.>) :: Parser a b -> c -> Parse a c
+ -- Action ignoring value
+into :: Parser a b -> (b -> Parser a c) -> Parser a c
+ -- Use a produced value in a parser.
+succeed b :: Parser a b
+ -- Always succeeds without consuming a token
+failP :: Parser a b
+ -- Always fails.
+many :: Parser a b -> Parser a [b]
+ -- Kleene star
+many1 :: Parser a b -> Parser a [b]
+ -- Kleene plus
+count :: Parser a b -> Int -> Parser a [b]
+ -- Parse an exact number of items
+sepBy1 :: Parser a b -> Parser a c -> Parser a [b]
+ -- Non-empty sequence of items separated by something
+sepBy :: Parser a b -> Parser a c -> Parser a [b]
+ -- Sequence of items separated by something
+lit :: (Eq a, Text a) => a -> Parser [a] a
+ -- Recognise a literal token from a list of tokens
+litp :: String -> (a->Bool) -> Parser [a] a
+ -- Recognise a token with a predicate.
+ -- The string is a description for error messages.
+testp :: String -> (a -> Bool) -> (Parser b a) -> Parser b a
+ -- Test a semantic value.
+token :: (a -> Either String (b, a)) -> Parser a b
+ -- General token recogniser.
+parse :: Parser a b -> a -> Either ([String], a) [(b, a)]
+ -- Do a parse. Return either error (possible tokens and rest
+ -- of tokens) or all possible parses.
+sParse :: (Text a) => (Parser [a] b) -> [a] -> Either String b
+ -- Simple parse. Return error message or result.
+\end{verbatim}
+
+%%%simpleLex :: String -> [String] -- A simple (but useful) lexical analyzer
+
+\item[\tr{Native}:]
+\index{Native module (HBC library)}%
+Functions to convert the primitive types \tr{Int}, \tr{Float}, and \tr{Double} to
+their native representation as a list of bytes (\tr{Char}). If such a list
+is read/written to a file it will have the same format as when, e.g.,
+C read/writes the same kind of data.
+\begin{verbatim}
+type Bytes = [Char] -- A byte stream is just a list of characters
+
+class Native a where
+ showBytes :: a -> Bytes -> Bytes
+ -- prepend the representation of an item the a byte stream
+ listShowBytes :: [a] -> Bytes -> Bytes
+ -- prepend the representation of a list of items to a stream
+ -- (may be more efficient than repeating showBytes).
+ readBytes :: Bytes -> Maybe (a, Bytes)
+ -- get an item from the stream and return the rest,
+ -- or fail if the stream is to short.
+ listReadBytes :: Int -> Bytes -> Maybe ([a], Bytes)
+ -- read n items from a stream.
+
+instance Native Int
+instance Native Float
+instance Native Double
+instance (Native a, Native b) => Native (a,b)
+ -- juxtaposition of the two items
+instance (Native a, Native b, Native c) => Native (a, b, c)
+ -- juxtaposition of the three items
+instance (Native a) => Native [a]
+ -- an item count in an Int followed by the items
+
+shortIntToBytes :: Int -> Bytes -> Bytes
+ -- Convert an Int to what corresponds to a short in C.
+bytesToShortInt :: Bytes -> Maybe (Int, Bytes)
+ -- Get a short from a byte stream and convert to an Int.
+
+showB :: (Native a) => a -> Bytes -- Simple interface to showBytes.
+readB :: (Native a) => Bytes -> a -- Simple interface to readBytes.
+\end{verbatim}
+
+\item[\tr{Number}:]
+\index{Number module (HBC library)}%
+Simple numbers that belong to all numeric classes and behave like
+a naive user would expect (except that printing is still ugly).
+(NB: GHC does not provide a magic way to use \tr{Numbers} everywhere,
+but you should be able to do it with normal \tr{import}ing and
+\tr{default}ing.)
+\begin{verbatim}
+data Number -- The type itself.
+instance ... -- All reasonable instances.
+isInteger :: Number -> Bool -- Test if a Number is an integer.
+\end{verbatim}
+\end{description}