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