[project @ 2002-05-09 13:16:29 by simonmar]
[ghc-base.git] / Foreign / C / Error.hs
1 {-# OPTIONS -fno-implicit-prelude -#include "HsBase.h" #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Foreign.C.Error
5 -- Copyright   :  (c) The FFI task force 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  ffi@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -- C-specific Marshalling support: Handling of C "errno" error codes
13 --
14 -----------------------------------------------------------------------------
15
16 module Foreign.C.Error (
17
18   -- Haskell representation for "errno" values
19   --
20   Errno(..),            -- instance: Eq
21   eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
22   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
23   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
24   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
25   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
26   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
27   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
28   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
29   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
30   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
31   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
32   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
33   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
34   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
35                         -- :: Errno
36   isValidErrno,         -- :: Errno -> Bool
37
38   -- access to the current thread's "errno" value
39   --
40   getErrno,             -- :: IO Errno
41   resetErrno,           -- :: IO ()
42
43   -- conversion of an "errno" value into IO error
44   --
45   errnoToIOError,       -- :: String       -- location
46                         -- -> Errno        -- errno
47                         -- -> Maybe Handle -- handle
48                         -- -> Maybe String -- filename
49                         -- -> IOError
50
51   -- throw current "errno" value
52   --
53   throwErrno,           -- ::                String               -> IO a
54
55   -- guards for IO operations that may fail
56   --
57   throwErrnoIf,         -- :: (a -> Bool) -> String -> IO a       -> IO a
58   throwErrnoIf_,        -- :: (a -> Bool) -> String -> IO a       -> IO ()
59   throwErrnoIfRetry,    -- :: (a -> Bool) -> String -> IO a       -> IO a
60   throwErrnoIfRetry_,   -- :: (a -> Bool) -> String -> IO a       -> IO ()
61   throwErrnoIfMinus1,   -- :: Num a 
62                         -- =>                String -> IO a       -> IO a
63   throwErrnoIfMinus1_,  -- :: Num a 
64                         -- =>                String -> IO a       -> IO ()
65   throwErrnoIfMinus1Retry,  
66                         -- :: Num a 
67                         -- =>                String -> IO a       -> IO a
68   throwErrnoIfMinus1Retry_,  
69                         -- :: Num a 
70                         -- =>                String -> IO a       -> IO ()
71   throwErrnoIfNull,     -- ::                String -> IO (Ptr a) -> IO (Ptr a)
72   throwErrnoIfNullRetry,-- ::                String -> IO (Ptr a) -> IO (Ptr a)
73
74   throwErrnoIfRetryMayBlock, 
75   throwErrnoIfRetryMayBlock_,
76   throwErrnoIfMinus1RetryMayBlock,
77   throwErrnoIfMinus1RetryMayBlock_,  
78   throwErrnoIfNullRetryMayBlock
79 ) where
80
81
82 -- this is were we get the CCONST_XXX definitions from that configure
83 -- calculated for us
84 --
85 #include "config.h"
86
87 -- system dependent imports
88 -- ------------------------
89
90 -- GHC allows us to get at the guts inside IO errors/exceptions
91 --
92 #if __GLASGOW_HASKELL__
93 import GHC.IOBase (Exception(..), IOException(..), IOErrorType(..))
94 #endif /* __GLASGOW_HASKELL__ */
95
96
97 -- regular imports
98 -- ---------------
99
100 import Foreign.Ptr
101 import Foreign.C.Types
102 import Foreign.C.String
103 import Foreign.Marshal.Error    ( void )
104 import Data.Maybe
105
106 #if __GLASGOW_HASKELL__
107 import GHC.Storable
108 import GHC.IOBase
109 import GHC.Num
110 import GHC.Base
111 #else
112 import System.IO                ( IOError, Handle, ioError )
113 #endif
114
115 -- "errno" type
116 -- ------------
117
118 -- import of C function that gives address of errno
119 -- This function exists because errno is a variable on some systems, but on
120 -- Windows it is a macro for a function...
121 -- [yes, global variables and thread safety don't really go hand-in-hand. -- sof]
122 foreign import ccall unsafe "ghcErrno" _errno :: Ptr CInt
123
124 -- Haskell representation for "errno" values
125 --
126 newtype Errno = Errno CInt
127
128 instance Eq Errno where
129   errno1@(Errno no1) == errno2@(Errno no2) 
130     | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
131     | otherwise                                  = False
132
133 -- common "errno" symbols
134 --
135 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
136   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
137   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
138   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
139   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
140   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
141   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
142   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
143   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
144   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
145   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
146   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
147   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
148   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV                    :: Errno
149 --
150 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
151 -- configure 
152 --
153 eOK             = Errno 0
154 e2BIG           = Errno (cCONST_E2BIG)
155 eACCES          = Errno (cCONST_EACCES)
156 eADDRINUSE      = Errno (cCONST_EADDRINUSE)
157 eADDRNOTAVAIL   = Errno (cCONST_EADDRNOTAVAIL)
158 eADV            = Errno (cCONST_EADV)
159 eAFNOSUPPORT    = Errno (cCONST_EAFNOSUPPORT)
160 eAGAIN          = Errno (cCONST_EAGAIN)
161 eALREADY        = Errno (cCONST_EALREADY)
162 eBADF           = Errno (cCONST_EBADF)
163 eBADMSG         = Errno (cCONST_EBADMSG)
164 eBADRPC         = Errno (cCONST_EBADRPC)
165 eBUSY           = Errno (cCONST_EBUSY)
166 eCHILD          = Errno (cCONST_ECHILD)
167 eCOMM           = Errno (cCONST_ECOMM)
168 eCONNABORTED    = Errno (cCONST_ECONNABORTED)
169 eCONNREFUSED    = Errno (cCONST_ECONNREFUSED)
170 eCONNRESET      = Errno (cCONST_ECONNRESET)
171 eDEADLK         = Errno (cCONST_EDEADLK)
172 eDESTADDRREQ    = Errno (cCONST_EDESTADDRREQ)
173 eDIRTY          = Errno (cCONST_EDIRTY)
174 eDOM            = Errno (cCONST_EDOM)
175 eDQUOT          = Errno (cCONST_EDQUOT)
176 eEXIST          = Errno (cCONST_EEXIST)
177 eFAULT          = Errno (cCONST_EFAULT)
178 eFBIG           = Errno (cCONST_EFBIG)
179 eFTYPE          = Errno (cCONST_EFTYPE)
180 eHOSTDOWN       = Errno (cCONST_EHOSTDOWN)
181 eHOSTUNREACH    = Errno (cCONST_EHOSTUNREACH)
182 eIDRM           = Errno (cCONST_EIDRM)
183 eILSEQ          = Errno (cCONST_EILSEQ)
184 eINPROGRESS     = Errno (cCONST_EINPROGRESS)
185 eINTR           = Errno (cCONST_EINTR)
186 eINVAL          = Errno (cCONST_EINVAL)
187 eIO             = Errno (cCONST_EIO)
188 eISCONN         = Errno (cCONST_EISCONN)
189 eISDIR          = Errno (cCONST_EISDIR)
190 eLOOP           = Errno (cCONST_ELOOP)
191 eMFILE          = Errno (cCONST_EMFILE)
192 eMLINK          = Errno (cCONST_EMLINK)
193 eMSGSIZE        = Errno (cCONST_EMSGSIZE)
194 eMULTIHOP       = Errno (cCONST_EMULTIHOP)
195 eNAMETOOLONG    = Errno (cCONST_ENAMETOOLONG)
196 eNETDOWN        = Errno (cCONST_ENETDOWN)
197 eNETRESET       = Errno (cCONST_ENETRESET)
198 eNETUNREACH     = Errno (cCONST_ENETUNREACH)
199 eNFILE          = Errno (cCONST_ENFILE)
200 eNOBUFS         = Errno (cCONST_ENOBUFS)
201 eNODATA         = Errno (cCONST_ENODATA)
202 eNODEV          = Errno (cCONST_ENODEV)
203 eNOENT          = Errno (cCONST_ENOENT)
204 eNOEXEC         = Errno (cCONST_ENOEXEC)
205 eNOLCK          = Errno (cCONST_ENOLCK)
206 eNOLINK         = Errno (cCONST_ENOLINK)
207 eNOMEM          = Errno (cCONST_ENOMEM)
208 eNOMSG          = Errno (cCONST_ENOMSG)
209 eNONET          = Errno (cCONST_ENONET)
210 eNOPROTOOPT     = Errno (cCONST_ENOPROTOOPT)
211 eNOSPC          = Errno (cCONST_ENOSPC)
212 eNOSR           = Errno (cCONST_ENOSR)
213 eNOSTR          = Errno (cCONST_ENOSTR)
214 eNOSYS          = Errno (cCONST_ENOSYS)
215 eNOTBLK         = Errno (cCONST_ENOTBLK)
216 eNOTCONN        = Errno (cCONST_ENOTCONN)
217 eNOTDIR         = Errno (cCONST_ENOTDIR)
218 eNOTEMPTY       = Errno (cCONST_ENOTEMPTY)
219 eNOTSOCK        = Errno (cCONST_ENOTSOCK)
220 eNOTTY          = Errno (cCONST_ENOTTY)
221 eNXIO           = Errno (cCONST_ENXIO)
222 eOPNOTSUPP      = Errno (cCONST_EOPNOTSUPP)
223 ePERM           = Errno (cCONST_EPERM)
224 ePFNOSUPPORT    = Errno (cCONST_EPFNOSUPPORT)
225 ePIPE           = Errno (cCONST_EPIPE)
226 ePROCLIM        = Errno (cCONST_EPROCLIM)
227 ePROCUNAVAIL    = Errno (cCONST_EPROCUNAVAIL)
228 ePROGMISMATCH   = Errno (cCONST_EPROGMISMATCH)
229 ePROGUNAVAIL    = Errno (cCONST_EPROGUNAVAIL)
230 ePROTO          = Errno (cCONST_EPROTO)
231 ePROTONOSUPPORT = Errno (cCONST_EPROTONOSUPPORT)
232 ePROTOTYPE      = Errno (cCONST_EPROTOTYPE)
233 eRANGE          = Errno (cCONST_ERANGE)
234 eREMCHG         = Errno (cCONST_EREMCHG)
235 eREMOTE         = Errno (cCONST_EREMOTE)
236 eROFS           = Errno (cCONST_EROFS)
237 eRPCMISMATCH    = Errno (cCONST_ERPCMISMATCH)
238 eRREMOTE        = Errno (cCONST_ERREMOTE)
239 eSHUTDOWN       = Errno (cCONST_ESHUTDOWN)
240 eSOCKTNOSUPPORT = Errno (cCONST_ESOCKTNOSUPPORT)
241 eSPIPE          = Errno (cCONST_ESPIPE)
242 eSRCH           = Errno (cCONST_ESRCH)
243 eSRMNT          = Errno (cCONST_ESRMNT)
244 eSTALE          = Errno (cCONST_ESTALE)
245 eTIME           = Errno (cCONST_ETIME)
246 eTIMEDOUT       = Errno (cCONST_ETIMEDOUT)
247 eTOOMANYREFS    = Errno (cCONST_ETOOMANYREFS)
248 eTXTBSY         = Errno (cCONST_ETXTBSY)
249 eUSERS          = Errno (cCONST_EUSERS)
250 eWOULDBLOCK     = Errno (cCONST_EWOULDBLOCK)
251 eXDEV           = Errno (cCONST_EXDEV)
252
253 -- checks whether the given errno value is supported on the current
254 -- architecture
255 --
256 isValidErrno               :: Errno -> Bool
257 --
258 -- the configure script sets all invalid "errno"s to -1
259 --
260 isValidErrno (Errno errno)  = errno /= -1
261
262
263 -- access to the current thread's "errno" value
264 -- --------------------------------------------
265
266 -- yield the current thread's "errno" value
267 --
268 getErrno :: IO Errno
269 getErrno  = do e <- peek _errno; return (Errno e)
270
271 -- set the current thread's "errno" value to 0
272 --
273 resetErrno :: IO ()
274 resetErrno  = poke _errno 0
275
276
277 -- throw current "errno" value
278 -- ---------------------------
279
280 -- the common case: throw an IO error based on a textual description
281 -- of the error location and the current thread's "errno" value
282 --
283 throwErrno     :: String -> IO a
284 throwErrno loc  =
285   do
286     errno <- getErrno
287     ioError (errnoToIOError loc errno Nothing Nothing)
288
289
290 -- guards for IO operations that may fail
291 -- --------------------------------------
292
293 -- guard an IO operation and throw an "errno" based exception of the result
294 -- value of the IO operation meets the given predicate
295 --
296 throwErrnoIf            :: (a -> Bool) -> String -> IO a -> IO a
297 throwErrnoIf pred loc f  = 
298   do
299     res <- f
300     if pred res then throwErrno loc else return res
301
302 -- as `throwErrnoIf', but discards the result
303 --
304 throwErrnoIf_            :: (a -> Bool) -> String -> IO a -> IO ()
305 throwErrnoIf_ pred loc f  = void $ throwErrnoIf pred loc f
306
307 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
308 -- flag `EINTR')
309 --
310 throwErrnoIfRetry            :: (a -> Bool) -> String -> IO a -> IO a
311 throwErrnoIfRetry pred loc f  = 
312   do
313     res <- f
314     if pred res
315       then do
316         err <- getErrno
317         if err == eINTR
318           then throwErrnoIfRetry pred loc f
319           else throwErrno loc
320       else return res
321
322 -- as `throwErrnoIfRetry', but checks for operations that would block and
323 -- executes an alternative action in that case.
324
325 throwErrnoIfRetryMayBlock  :: (a -> Bool) -> String -> IO a -> IO b -> IO a
326 throwErrnoIfRetryMayBlock pred loc f on_block  = 
327   do
328     res <- f
329     if pred res
330       then do
331         err <- getErrno
332         if err == eINTR
333           then throwErrnoIfRetryMayBlock pred loc f on_block
334           else if err == eWOULDBLOCK || err == eAGAIN
335                  then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
336                  else throwErrno loc
337       else return res
338
339 -- as `throwErrnoIfRetry', but discards the result
340 --
341 throwErrnoIfRetry_            :: (a -> Bool) -> String -> IO a -> IO ()
342 throwErrnoIfRetry_ pred loc f  = void $ throwErrnoIfRetry pred loc f
343
344 -- as `throwErrnoIfRetryMayBlock', but discards the result
345 --
346 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
347 throwErrnoIfRetryMayBlock_ pred loc f on_block 
348   = void $ throwErrnoIfRetryMayBlock pred loc f on_block
349
350 -- throws "errno" if a result of "-1" is returned
351 --
352 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
353 throwErrnoIfMinus1  = throwErrnoIf (== -1)
354
355 -- as `throwErrnoIfMinus1', but discards the result
356 --
357 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
358 throwErrnoIfMinus1_  = throwErrnoIf_ (== -1)
359
360 -- throws "errno" if a result of "-1" is returned, but retries in case of an
361 -- interrupted operation
362 --
363 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
364 throwErrnoIfMinus1Retry  = throwErrnoIfRetry (== -1)
365
366 -- as `throwErrnoIfMinus1', but discards the result
367 --
368 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
369 throwErrnoIfMinus1Retry_  = throwErrnoIfRetry_ (== -1)
370
371 -- as throwErrnoIfMinus1Retry, but checks for operations that would block
372 --
373 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
374 throwErrnoIfMinus1RetryMayBlock  = throwErrnoIfRetryMayBlock (== -1)
375
376 -- as `throwErrnoIfMinus1RetryMayBlock', but discards the result
377 --
378 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
379 throwErrnoIfMinus1RetryMayBlock_  = throwErrnoIfRetryMayBlock_ (== -1)
380
381 -- throws "errno" if a result of a NULL pointer is returned
382 --
383 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
384 throwErrnoIfNull  = throwErrnoIf (== nullPtr)
385
386 -- throws "errno" if a result of a NULL pointer is returned, but retries in
387 -- case of an interrupted operation
388 --
389 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
390 throwErrnoIfNullRetry  = throwErrnoIfRetry (== nullPtr)
391
392 -- as throwErrnoIfNullRetry, but checks for operations that would block
393 --
394 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
395 throwErrnoIfNullRetryMayBlock  = throwErrnoIfRetryMayBlock (== nullPtr)
396
397 -- conversion of an "errno" value into IO error
398 -- --------------------------------------------
399
400 -- convert a location string, an "errno" value, an optional handle,
401 -- and an optional filename into a matching IO error
402 --
403 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
404 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
405     str <- strerror errno >>= peekCString
406 #if __GLASGOW_HASKELL__
407     return (IOException (IOError maybeHdl errType loc str maybeName))
408     where
409     errType
410         | errno == eOK             = OtherError
411         | errno == e2BIG           = ResourceExhausted
412         | errno == eACCES          = PermissionDenied
413         | errno == eADDRINUSE      = ResourceBusy
414         | errno == eADDRNOTAVAIL   = UnsupportedOperation
415         | errno == eADV            = OtherError
416         | errno == eAFNOSUPPORT    = UnsupportedOperation
417         | errno == eAGAIN          = ResourceExhausted
418         | errno == eALREADY        = AlreadyExists
419         | errno == eBADF           = OtherError
420         | errno == eBADMSG         = InappropriateType
421         | errno == eBADRPC         = OtherError
422         | errno == eBUSY           = ResourceBusy
423         | errno == eCHILD          = NoSuchThing
424         | errno == eCOMM           = ResourceVanished
425         | errno == eCONNABORTED    = OtherError
426         | errno == eCONNREFUSED    = NoSuchThing
427         | errno == eCONNRESET      = ResourceVanished
428         | errno == eDEADLK         = ResourceBusy
429         | errno == eDESTADDRREQ    = InvalidArgument
430         | errno == eDIRTY          = UnsatisfiedConstraints
431         | errno == eDOM            = InvalidArgument
432         | errno == eDQUOT          = PermissionDenied
433         | errno == eEXIST          = AlreadyExists
434         | errno == eFAULT          = OtherError
435         | errno == eFBIG           = PermissionDenied
436         | errno == eFTYPE          = InappropriateType
437         | errno == eHOSTDOWN       = NoSuchThing
438         | errno == eHOSTUNREACH    = NoSuchThing
439         | errno == eIDRM           = ResourceVanished
440         | errno == eILSEQ          = InvalidArgument
441         | errno == eINPROGRESS     = AlreadyExists
442         | errno == eINTR           = Interrupted
443         | errno == eINVAL          = InvalidArgument
444         | errno == eIO             = HardwareFault
445         | errno == eISCONN         = AlreadyExists
446         | errno == eISDIR          = InappropriateType
447         | errno == eLOOP           = InvalidArgument
448         | errno == eMFILE          = ResourceExhausted
449         | errno == eMLINK          = ResourceExhausted
450         | errno == eMSGSIZE        = ResourceExhausted
451         | errno == eMULTIHOP       = UnsupportedOperation
452         | errno == eNAMETOOLONG    = InvalidArgument
453         | errno == eNETDOWN        = ResourceVanished
454         | errno == eNETRESET       = ResourceVanished
455         | errno == eNETUNREACH     = NoSuchThing
456         | errno == eNFILE          = ResourceExhausted
457         | errno == eNOBUFS         = ResourceExhausted
458         | errno == eNODATA         = NoSuchThing
459         | errno == eNODEV          = UnsupportedOperation
460         | errno == eNOENT          = NoSuchThing
461         | errno == eNOEXEC         = InvalidArgument
462         | errno == eNOLCK          = ResourceExhausted
463         | errno == eNOLINK         = ResourceVanished
464         | errno == eNOMEM          = ResourceExhausted
465         | errno == eNOMSG          = NoSuchThing
466         | errno == eNONET          = NoSuchThing
467         | errno == eNOPROTOOPT     = UnsupportedOperation
468         | errno == eNOSPC          = ResourceExhausted
469         | errno == eNOSR           = ResourceExhausted
470         | errno == eNOSTR          = InvalidArgument
471         | errno == eNOSYS          = UnsupportedOperation
472         | errno == eNOTBLK         = InvalidArgument
473         | errno == eNOTCONN        = InvalidArgument
474         | errno == eNOTDIR         = InappropriateType
475         | errno == eNOTEMPTY       = UnsatisfiedConstraints
476         | errno == eNOTSOCK        = InvalidArgument
477         | errno == eNOTTY          = IllegalOperation
478         | errno == eNXIO           = NoSuchThing
479         | errno == eOPNOTSUPP      = UnsupportedOperation
480         | errno == ePERM           = PermissionDenied
481         | errno == ePFNOSUPPORT    = UnsupportedOperation
482         | errno == ePIPE           = ResourceVanished
483         | errno == ePROCLIM        = PermissionDenied
484         | errno == ePROCUNAVAIL    = UnsupportedOperation
485         | errno == ePROGMISMATCH   = ProtocolError
486         | errno == ePROGUNAVAIL    = UnsupportedOperation
487         | errno == ePROTO          = ProtocolError
488         | errno == ePROTONOSUPPORT = ProtocolError
489         | errno == ePROTOTYPE      = ProtocolError
490         | errno == eRANGE          = UnsupportedOperation
491         | errno == eREMCHG         = ResourceVanished
492         | errno == eREMOTE         = IllegalOperation
493         | errno == eROFS           = PermissionDenied
494         | errno == eRPCMISMATCH    = ProtocolError
495         | errno == eRREMOTE        = IllegalOperation
496         | errno == eSHUTDOWN       = IllegalOperation
497         | errno == eSOCKTNOSUPPORT = UnsupportedOperation
498         | errno == eSPIPE          = UnsupportedOperation
499         | errno == eSRCH           = NoSuchThing
500         | errno == eSRMNT          = UnsatisfiedConstraints
501         | errno == eSTALE          = ResourceVanished
502         | errno == eTIME           = TimeExpired
503         | errno == eTIMEDOUT       = TimeExpired
504         | errno == eTOOMANYREFS    = ResourceExhausted
505         | errno == eTXTBSY         = ResourceBusy
506         | errno == eUSERS          = ResourceExhausted
507         | errno == eWOULDBLOCK     = OtherError
508         | errno == eXDEV           = UnsupportedOperation
509         | otherwise                = OtherError
510 #else
511     return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
512 #endif
513
514 foreign import ccall unsafe strerror :: Errno -> IO (Ptr CChar)
515
516
517 -- Dreadfully tedious callouts to wrappers which define  the
518 -- actual values for the error codes.
519 foreign import ccall unsafe "prel_error_E2BIG" cCONST_E2BIG :: CInt
520 foreign import ccall unsafe "prel_error_EACCES" cCONST_EACCES :: CInt
521 foreign import ccall unsafe "prel_error_EADDRINUSE" cCONST_EADDRINUSE :: CInt
522 foreign import ccall unsafe "prel_error_EADDRNOTAVAIL" cCONST_EADDRNOTAVAIL :: CInt
523 foreign import ccall unsafe "prel_error_EADV" cCONST_EADV :: CInt
524 foreign import ccall unsafe "prel_error_EAFNOSUPPORT" cCONST_EAFNOSUPPORT :: CInt
525 foreign import ccall unsafe "prel_error_EAGAIN" cCONST_EAGAIN :: CInt
526 foreign import ccall unsafe "prel_error_EALREADY" cCONST_EALREADY :: CInt
527 foreign import ccall unsafe "prel_error_EBADF" cCONST_EBADF :: CInt
528 foreign import ccall unsafe "prel_error_EBADMSG" cCONST_EBADMSG :: CInt
529 foreign import ccall unsafe "prel_error_EBADRPC" cCONST_EBADRPC :: CInt
530 foreign import ccall unsafe "prel_error_EBUSY" cCONST_EBUSY :: CInt
531 foreign import ccall unsafe "prel_error_ECHILD" cCONST_ECHILD :: CInt
532 foreign import ccall unsafe "prel_error_ECOMM" cCONST_ECOMM :: CInt
533 foreign import ccall unsafe "prel_error_ECONNABORTED" cCONST_ECONNABORTED :: CInt
534 foreign import ccall unsafe "prel_error_ECONNREFUSED" cCONST_ECONNREFUSED :: CInt
535 foreign import ccall unsafe "prel_error_ECONNRESET" cCONST_ECONNRESET :: CInt
536 foreign import ccall unsafe "prel_error_EDEADLK" cCONST_EDEADLK :: CInt
537 foreign import ccall unsafe "prel_error_EDESTADDRREQ" cCONST_EDESTADDRREQ :: CInt
538 foreign import ccall unsafe "prel_error_EDIRTY" cCONST_EDIRTY :: CInt
539 foreign import ccall unsafe "prel_error_EDOM" cCONST_EDOM :: CInt
540 foreign import ccall unsafe "prel_error_EDQUOT" cCONST_EDQUOT :: CInt
541 foreign import ccall unsafe "prel_error_EEXIST" cCONST_EEXIST :: CInt
542 foreign import ccall unsafe "prel_error_EFAULT" cCONST_EFAULT :: CInt
543 foreign import ccall unsafe "prel_error_EFBIG" cCONST_EFBIG :: CInt
544 foreign import ccall unsafe "prel_error_EFTYPE" cCONST_EFTYPE :: CInt
545 foreign import ccall unsafe "prel_error_EHOSTDOWN" cCONST_EHOSTDOWN :: CInt
546 foreign import ccall unsafe "prel_error_EHOSTUNREACH" cCONST_EHOSTUNREACH :: CInt
547 foreign import ccall unsafe "prel_error_EIDRM" cCONST_EIDRM :: CInt
548 foreign import ccall unsafe "prel_error_EILSEQ" cCONST_EILSEQ :: CInt
549 foreign import ccall unsafe "prel_error_EINPROGRESS" cCONST_EINPROGRESS :: CInt
550 foreign import ccall unsafe "prel_error_EINTR" cCONST_EINTR :: CInt
551 foreign import ccall unsafe "prel_error_EINVAL" cCONST_EINVAL :: CInt
552 foreign import ccall unsafe "prel_error_EIO" cCONST_EIO :: CInt
553 foreign import ccall unsafe "prel_error_EISCONN" cCONST_EISCONN :: CInt
554 foreign import ccall unsafe "prel_error_EISDIR" cCONST_EISDIR :: CInt
555 foreign import ccall unsafe "prel_error_ELOOP" cCONST_ELOOP :: CInt
556 foreign import ccall unsafe "prel_error_EMFILE" cCONST_EMFILE :: CInt
557 foreign import ccall unsafe "prel_error_EMLINK" cCONST_EMLINK :: CInt
558 foreign import ccall unsafe "prel_error_EMSGSIZE" cCONST_EMSGSIZE :: CInt
559 foreign import ccall unsafe "prel_error_EMULTIHOP" cCONST_EMULTIHOP :: CInt
560 foreign import ccall unsafe "prel_error_ENAMETOOLONG" cCONST_ENAMETOOLONG :: CInt
561 foreign import ccall unsafe "prel_error_ENETDOWN" cCONST_ENETDOWN :: CInt
562 foreign import ccall unsafe "prel_error_ENETRESET" cCONST_ENETRESET :: CInt
563 foreign import ccall unsafe "prel_error_ENETUNREACH" cCONST_ENETUNREACH :: CInt
564 foreign import ccall unsafe "prel_error_ENFILE" cCONST_ENFILE :: CInt
565 foreign import ccall unsafe "prel_error_ENOBUFS" cCONST_ENOBUFS :: CInt
566 foreign import ccall unsafe "prel_error_ENODATA" cCONST_ENODATA :: CInt
567 foreign import ccall unsafe "prel_error_ENODEV" cCONST_ENODEV :: CInt
568 foreign import ccall unsafe "prel_error_ENOENT" cCONST_ENOENT :: CInt
569 foreign import ccall unsafe "prel_error_ENOEXEC" cCONST_ENOEXEC :: CInt
570 foreign import ccall unsafe "prel_error_ENOLCK" cCONST_ENOLCK :: CInt
571 foreign import ccall unsafe "prel_error_ENOLINK" cCONST_ENOLINK :: CInt
572 foreign import ccall unsafe "prel_error_ENOMEM" cCONST_ENOMEM :: CInt
573 foreign import ccall unsafe "prel_error_ENOMSG" cCONST_ENOMSG :: CInt
574 foreign import ccall unsafe "prel_error_ENONET" cCONST_ENONET :: CInt
575 foreign import ccall unsafe "prel_error_ENOPROTOOPT" cCONST_ENOPROTOOPT :: CInt
576 foreign import ccall unsafe "prel_error_ENOSPC" cCONST_ENOSPC :: CInt
577 foreign import ccall unsafe "prel_error_ENOSR" cCONST_ENOSR :: CInt
578 foreign import ccall unsafe "prel_error_ENOSTR" cCONST_ENOSTR :: CInt
579 foreign import ccall unsafe "prel_error_ENOSYS" cCONST_ENOSYS :: CInt
580 foreign import ccall unsafe "prel_error_ENOTBLK" cCONST_ENOTBLK :: CInt
581 foreign import ccall unsafe "prel_error_ENOTCONN" cCONST_ENOTCONN :: CInt
582 foreign import ccall unsafe "prel_error_ENOTDIR" cCONST_ENOTDIR :: CInt
583 foreign import ccall unsafe "prel_error_ENOTEMPTY" cCONST_ENOTEMPTY :: CInt
584 foreign import ccall unsafe "prel_error_ENOTSOCK" cCONST_ENOTSOCK :: CInt
585 foreign import ccall unsafe "prel_error_ENOTTY" cCONST_ENOTTY :: CInt
586 foreign import ccall unsafe "prel_error_ENXIO" cCONST_ENXIO :: CInt
587 foreign import ccall unsafe "prel_error_EOPNOTSUPP" cCONST_EOPNOTSUPP :: CInt
588 foreign import ccall unsafe "prel_error_EPERM" cCONST_EPERM :: CInt
589 foreign import ccall unsafe "prel_error_EPFNOSUPPORT" cCONST_EPFNOSUPPORT :: CInt
590 foreign import ccall unsafe "prel_error_EPIPE" cCONST_EPIPE :: CInt
591 foreign import ccall unsafe "prel_error_EPROCLIM" cCONST_EPROCLIM :: CInt
592 foreign import ccall unsafe "prel_error_EPROCUNAVAIL" cCONST_EPROCUNAVAIL :: CInt
593 foreign import ccall unsafe "prel_error_EPROGMISMATCH" cCONST_EPROGMISMATCH :: CInt
594 foreign import ccall unsafe "prel_error_EPROGUNAVAIL" cCONST_EPROGUNAVAIL :: CInt
595 foreign import ccall unsafe "prel_error_EPROTO" cCONST_EPROTO :: CInt
596 foreign import ccall unsafe "prel_error_EPROTONOSUPPORT" cCONST_EPROTONOSUPPORT :: CInt
597 foreign import ccall unsafe "prel_error_EPROTOTYPE" cCONST_EPROTOTYPE :: CInt
598 foreign import ccall unsafe "prel_error_ERANGE" cCONST_ERANGE :: CInt
599 foreign import ccall unsafe "prel_error_EREMCHG" cCONST_EREMCHG :: CInt
600 foreign import ccall unsafe "prel_error_EREMOTE" cCONST_EREMOTE :: CInt
601 foreign import ccall unsafe "prel_error_EROFS" cCONST_EROFS :: CInt
602 foreign import ccall unsafe "prel_error_ERPCMISMATCH" cCONST_ERPCMISMATCH :: CInt
603 foreign import ccall unsafe "prel_error_ERREMOTE" cCONST_ERREMOTE :: CInt
604 foreign import ccall unsafe "prel_error_ESHUTDOWN" cCONST_ESHUTDOWN :: CInt
605 foreign import ccall unsafe "prel_error_ESOCKTNOSUPPORT" cCONST_ESOCKTNOSUPPORT :: CInt
606 foreign import ccall unsafe "prel_error_ESPIPE" cCONST_ESPIPE :: CInt
607 foreign import ccall unsafe "prel_error_ESRCH" cCONST_ESRCH :: CInt
608 foreign import ccall unsafe "prel_error_ESRMNT" cCONST_ESRMNT :: CInt
609 foreign import ccall unsafe "prel_error_ESTALE" cCONST_ESTALE :: CInt
610 foreign import ccall unsafe "prel_error_ETIME" cCONST_ETIME :: CInt
611 foreign import ccall unsafe "prel_error_ETIMEDOUT" cCONST_ETIMEDOUT :: CInt
612 foreign import ccall unsafe "prel_error_ETOOMANYREFS" cCONST_ETOOMANYREFS :: CInt
613 foreign import ccall unsafe "prel_error_ETXTBSY" cCONST_ETXTBSY :: CInt
614 foreign import ccall unsafe "prel_error_EUSERS" cCONST_EUSERS :: CInt
615 foreign import ccall unsafe "prel_error_EWOULDBLOCK" cCONST_EWOULDBLOCK :: CInt
616 foreign import ccall unsafe "prel_error_EXDEV" cCONST_EXDEV :: CInt
617