2 % (c) The GRASP/AQUA Project, Glasgow University, 1995-1996
4 \section[PosixUtil]{Haskell 1.3 POSIX utilities}
10 import PrelST -- ST representation
11 import PrelIOBase -- IOError representation
19 import PackedString ( packCBytesST, psToByteArrayST, unpackPS )
21 import PrelArr (StateAndMutableByteArray#(..), StateAndByteArray#(..))
24 First, all of the major Posix data types, to avoid any recursive dependencies
35 type ProcessGroupID = ProcessID
39 instance CReturnable Fd
42 (FD# x#) == (FD# y#) = x# ==# y#
46 intToFd (I# fd#) = FD# fd#
49 fdToInt (FD# x#) = I# x#
52 Now some local functions that shouldn't go outside this library.
54 Fail with a SystemError. Normally, we do not try to re-interpret
55 POSIX error numbers, so most routines in this file will only fail
56 with SystemError. The only exceptions are (1) those routines where
57 failure of some kind may be considered ``normal''...e.g. getpwnam()
58 for a non-existent user, or (2) those routines which do not set
62 syserr :: String -> IO a
63 syserr str = fail (IOError Nothing -- ToDo: better
67 -- Allocate a mutable array of characters with no indices.
69 allocChars :: Int -> IO (MutableByteArray RealWorld ())
70 allocChars (I# size#) = IO $ \ s# ->
71 case newCharArray# size# s# of
72 StateAndMutableByteArray# s2# barr# ->
73 IOok s2# (MutableByteArray bot barr#)
75 bot = error "PosixUtil.allocChars"
77 -- Allocate a mutable array of words with no indices
79 allocWords :: Int -> IO (MutableByteArray RealWorld ())
80 allocWords (I# size#) = IO $ \ s# ->
81 case newIntArray# size# s# of
82 StateAndMutableByteArray# s2# barr# ->
83 IOok s2# (MutableByteArray bot barr#)
85 bot = error "PosixUtil.allocWords"
87 -- Freeze these index-free mutable arrays
89 freeze :: MutableByteArray RealWorld () -> IO (ByteArray ())
90 freeze (MutableByteArray ixs arr#) = IO $ \ s# ->
91 case unsafeFreezeByteArray# arr# s# of
92 StateAndByteArray# s2# frozen# ->
93 IOok s2# (ByteArray ixs frozen#)
95 -- Copy a null-terminated string from outside the heap to
96 -- Haskellized nonsense inside the heap
98 strcpy :: Addr -> IO String
100 | str == ``NULL'' = return ""
102 _ccall_ strlen str >>= \ len ->
103 stToIO (packCBytesST len str) >>= \ ps ->
106 -- Turn a string list into a NULL-terminated vector of null-terminated
107 -- strings No indices...I hate indices. Death to Ix.
109 vectorize :: [String] -> IO (ByteArray ())
111 arr <- allocWords (len + 1)
118 fill :: MutableByteArray RealWorld () -> Int -> [String] -> IO ()
120 _casm_ ``((PP_)%0)[%1] = NULL;'' arr n
122 stToIO (psToByteArrayST x) >>= \ barr ->
123 _casm_ ``((PP_)%0)[%1] = (P_)%2;'' arr n barr
127 -- Turn a NULL-terminated vector of null-terminated strings into a string list
129 unvectorize :: Addr -> Int -> IO [String]
131 | str == ``NULL'' = return []
133 strcpy str >>= \ x ->
134 unvectorize ptr (n+1) >>= \ xs ->
137 str = indexAddrOffAddr ptr n
139 -- common templates for system calls
141 nonzero_error :: IO Int -> String -> IO ()
142 nonzero_error io err = do
148 minusone_error :: IO Int -> String -> IO ()
149 minusone_error io err = do
155 -- IO versions of a few ST functions.
157 psToByteArrayIO = stToIO . psToByteArrayST