SafeHaskell: Added SafeHaskell to base
[ghc.git] / libraries / base / Foreign / C / Error.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE CPP, NoImplicitPrelude, ForeignFunctionInterface #-}
3 {-# OPTIONS_GHC -#include "HsBase.h" #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : Foreign.C.Error
8 -- Copyright : (c) The FFI task force 2001
9 -- License : BSD-style (see the file libraries/base/LICENSE)
10 --
11 -- Maintainer : ffi@haskell.org
12 -- Stability : provisional
13 -- Portability : portable
14 --
15 -- C-specific Marshalling support: Handling of C \"errno\" error codes.
16 --
17 -----------------------------------------------------------------------------
18
19 module Foreign.C.Error (
20
21 -- * Haskell representations of @errno@ values
22
23 Errno(..), -- instance: Eq
24
25 -- ** Common @errno@ symbols
26 -- | Different operating systems and\/or C libraries often support
27 -- different values of @errno@. This module defines the common values,
28 -- but due to the open definition of 'Errno' users may add definitions
29 -- which are not predefined.
30 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
31 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
32 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
33 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
34 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
35 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
36 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
37 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
38 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
39 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
40 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
41 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
42 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
43 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
44
45 -- ** 'Errno' functions
46 -- :: Errno
47 isValidErrno, -- :: Errno -> Bool
48
49 -- access to the current thread's "errno" value
50 --
51 getErrno, -- :: IO Errno
52 resetErrno, -- :: IO ()
53
54 -- conversion of an "errno" value into IO error
55 --
56 errnoToIOError, -- :: String -- location
57 -- -> Errno -- errno
58 -- -> Maybe Handle -- handle
59 -- -> Maybe String -- filename
60 -- -> IOError
61
62 -- throw current "errno" value
63 --
64 throwErrno, -- :: String -> IO a
65
66 -- ** Guards for IO operations that may fail
67
68 throwErrnoIf, -- :: (a -> Bool) -> String -> IO a -> IO a
69 throwErrnoIf_, -- :: (a -> Bool) -> String -> IO a -> IO ()
70 throwErrnoIfRetry, -- :: (a -> Bool) -> String -> IO a -> IO a
71 throwErrnoIfRetry_, -- :: (a -> Bool) -> String -> IO a -> IO ()
72 throwErrnoIfMinus1, -- :: Num a
73 -- => String -> IO a -> IO a
74 throwErrnoIfMinus1_, -- :: Num a
75 -- => String -> IO a -> IO ()
76 throwErrnoIfMinus1Retry,
77 -- :: Num a
78 -- => String -> IO a -> IO a
79 throwErrnoIfMinus1Retry_,
80 -- :: Num a
81 -- => String -> IO a -> IO ()
82 throwErrnoIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
83 throwErrnoIfNullRetry,-- :: String -> IO (Ptr a) -> IO (Ptr a)
84
85 throwErrnoIfRetryMayBlock,
86 throwErrnoIfRetryMayBlock_,
87 throwErrnoIfMinus1RetryMayBlock,
88 throwErrnoIfMinus1RetryMayBlock_,
89 throwErrnoIfNullRetryMayBlock,
90
91 throwErrnoPath,
92 throwErrnoPathIf,
93 throwErrnoPathIf_,
94 throwErrnoPathIfNull,
95 throwErrnoPathIfMinus1,
96 throwErrnoPathIfMinus1_,
97 ) where
98
99
100 -- this is were we get the CONST_XXX definitions from that configure
101 -- calculated for us
102 --
103 #ifndef __NHC__
104 #include "HsBaseConfig.h"
105 #endif
106
107 import Foreign.Ptr
108 import Foreign.C.Types
109 import Foreign.C.String
110 import Foreign.Marshal.Error ( void )
111 import Data.Maybe
112
113 #if __GLASGOW_HASKELL__
114 import GHC.IO
115 import GHC.IO.Exception
116 import GHC.IO.Handle.Types
117 import GHC.Num
118 import GHC.Base
119 #elif __HUGS__
120 import Hugs.Prelude ( Handle, IOError, ioError )
121 import System.IO.Unsafe ( unsafePerformIO )
122 #else
123 import System.IO ( Handle )
124 import System.IO.Error ( IOError, ioError )
125 import System.IO.Unsafe ( unsafePerformIO )
126 import Foreign.Storable ( Storable(poke,peek) )
127 #endif
128
129 #ifdef __HUGS__
130 {-# CFILES cbits/PrelIOUtils.c #-}
131 #endif
132
133
134 -- "errno" type
135 -- ------------
136
137 -- | Haskell representation for @errno@ values.
138 -- The implementation is deliberately exposed, to allow users to add
139 -- their own definitions of 'Errno' values.
140
141 newtype Errno = Errno CInt
142
143 instance Eq Errno where
144 errno1@(Errno no1) == errno2@(Errno no2)
145 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
146 | otherwise = False
147
148 -- common "errno" symbols
149 --
150 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
151 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
152 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
153 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
154 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
155 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
156 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
157 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
158 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
159 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
160 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
161 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
162 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
163 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV :: Errno
164 --
165 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
166 -- configure
167 --
168 eOK = Errno 0
169 #ifdef __NHC__
170 #include "Errno.hs"
171 #else
172 e2BIG = Errno (CONST_E2BIG)
173 eACCES = Errno (CONST_EACCES)
174 eADDRINUSE = Errno (CONST_EADDRINUSE)
175 eADDRNOTAVAIL = Errno (CONST_EADDRNOTAVAIL)
176 eADV = Errno (CONST_EADV)
177 eAFNOSUPPORT = Errno (CONST_EAFNOSUPPORT)
178 eAGAIN = Errno (CONST_EAGAIN)
179 eALREADY = Errno (CONST_EALREADY)
180 eBADF = Errno (CONST_EBADF)
181 eBADMSG = Errno (CONST_EBADMSG)
182 eBADRPC = Errno (CONST_EBADRPC)
183 eBUSY = Errno (CONST_EBUSY)
184 eCHILD = Errno (CONST_ECHILD)
185 eCOMM = Errno (CONST_ECOMM)
186 eCONNABORTED = Errno (CONST_ECONNABORTED)
187 eCONNREFUSED = Errno (CONST_ECONNREFUSED)
188 eCONNRESET = Errno (CONST_ECONNRESET)
189 eDEADLK = Errno (CONST_EDEADLK)
190 eDESTADDRREQ = Errno (CONST_EDESTADDRREQ)
191 eDIRTY = Errno (CONST_EDIRTY)
192 eDOM = Errno (CONST_EDOM)
193 eDQUOT = Errno (CONST_EDQUOT)
194 eEXIST = Errno (CONST_EEXIST)
195 eFAULT = Errno (CONST_EFAULT)
196 eFBIG = Errno (CONST_EFBIG)
197 eFTYPE = Errno (CONST_EFTYPE)
198 eHOSTDOWN = Errno (CONST_EHOSTDOWN)
199 eHOSTUNREACH = Errno (CONST_EHOSTUNREACH)
200 eIDRM = Errno (CONST_EIDRM)
201 eILSEQ = Errno (CONST_EILSEQ)
202 eINPROGRESS = Errno (CONST_EINPROGRESS)
203 eINTR = Errno (CONST_EINTR)
204 eINVAL = Errno (CONST_EINVAL)
205 eIO = Errno (CONST_EIO)
206 eISCONN = Errno (CONST_EISCONN)
207 eISDIR = Errno (CONST_EISDIR)
208 eLOOP = Errno (CONST_ELOOP)
209 eMFILE = Errno (CONST_EMFILE)
210 eMLINK = Errno (CONST_EMLINK)
211 eMSGSIZE = Errno (CONST_EMSGSIZE)
212 eMULTIHOP = Errno (CONST_EMULTIHOP)
213 eNAMETOOLONG = Errno (CONST_ENAMETOOLONG)
214 eNETDOWN = Errno (CONST_ENETDOWN)
215 eNETRESET = Errno (CONST_ENETRESET)
216 eNETUNREACH = Errno (CONST_ENETUNREACH)
217 eNFILE = Errno (CONST_ENFILE)
218 eNOBUFS = Errno (CONST_ENOBUFS)
219 eNODATA = Errno (CONST_ENODATA)
220 eNODEV = Errno (CONST_ENODEV)
221 eNOENT = Errno (CONST_ENOENT)
222 eNOEXEC = Errno (CONST_ENOEXEC)
223 eNOLCK = Errno (CONST_ENOLCK)
224 eNOLINK = Errno (CONST_ENOLINK)
225 eNOMEM = Errno (CONST_ENOMEM)
226 eNOMSG = Errno (CONST_ENOMSG)
227 eNONET = Errno (CONST_ENONET)
228 eNOPROTOOPT = Errno (CONST_ENOPROTOOPT)
229 eNOSPC = Errno (CONST_ENOSPC)
230 eNOSR = Errno (CONST_ENOSR)
231 eNOSTR = Errno (CONST_ENOSTR)
232 eNOSYS = Errno (CONST_ENOSYS)
233 eNOTBLK = Errno (CONST_ENOTBLK)
234 eNOTCONN = Errno (CONST_ENOTCONN)
235 eNOTDIR = Errno (CONST_ENOTDIR)
236 eNOTEMPTY = Errno (CONST_ENOTEMPTY)
237 eNOTSOCK = Errno (CONST_ENOTSOCK)
238 eNOTTY = Errno (CONST_ENOTTY)
239 eNXIO = Errno (CONST_ENXIO)
240 eOPNOTSUPP = Errno (CONST_EOPNOTSUPP)
241 ePERM = Errno (CONST_EPERM)
242 ePFNOSUPPORT = Errno (CONST_EPFNOSUPPORT)
243 ePIPE = Errno (CONST_EPIPE)
244 ePROCLIM = Errno (CONST_EPROCLIM)
245 ePROCUNAVAIL = Errno (CONST_EPROCUNAVAIL)
246 ePROGMISMATCH = Errno (CONST_EPROGMISMATCH)
247 ePROGUNAVAIL = Errno (CONST_EPROGUNAVAIL)
248 ePROTO = Errno (CONST_EPROTO)
249 ePROTONOSUPPORT = Errno (CONST_EPROTONOSUPPORT)
250 ePROTOTYPE = Errno (CONST_EPROTOTYPE)
251 eRANGE = Errno (CONST_ERANGE)
252 eREMCHG = Errno (CONST_EREMCHG)
253 eREMOTE = Errno (CONST_EREMOTE)
254 eROFS = Errno (CONST_EROFS)
255 eRPCMISMATCH = Errno (CONST_ERPCMISMATCH)
256 eRREMOTE = Errno (CONST_ERREMOTE)
257 eSHUTDOWN = Errno (CONST_ESHUTDOWN)
258 eSOCKTNOSUPPORT = Errno (CONST_ESOCKTNOSUPPORT)
259 eSPIPE = Errno (CONST_ESPIPE)
260 eSRCH = Errno (CONST_ESRCH)
261 eSRMNT = Errno (CONST_ESRMNT)
262 eSTALE = Errno (CONST_ESTALE)
263 eTIME = Errno (CONST_ETIME)
264 eTIMEDOUT = Errno (CONST_ETIMEDOUT)
265 eTOOMANYREFS = Errno (CONST_ETOOMANYREFS)
266 eTXTBSY = Errno (CONST_ETXTBSY)
267 eUSERS = Errno (CONST_EUSERS)
268 eWOULDBLOCK = Errno (CONST_EWOULDBLOCK)
269 eXDEV = Errno (CONST_EXDEV)
270 #endif
271
272 -- | Yield 'True' if the given 'Errno' value is valid on the system.
273 -- This implies that the 'Eq' instance of 'Errno' is also system dependent
274 -- as it is only defined for valid values of 'Errno'.
275 --
276 isValidErrno :: Errno -> Bool
277 --
278 -- the configure script sets all invalid "errno"s to -1
279 --
280 isValidErrno (Errno errno) = errno /= -1
281
282
283 -- access to the current thread's "errno" value
284 -- --------------------------------------------
285
286 -- | Get the current value of @errno@ in the current thread.
287 --
288 getErrno :: IO Errno
289
290 -- We must call a C function to get the value of errno in general. On
291 -- threaded systems, errno is hidden behind a C macro so that each OS
292 -- thread gets its own copy.
293 #ifdef __NHC__
294 getErrno = do e <- peek _errno; return (Errno e)
295 foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt
296 #else
297 getErrno = do e <- get_errno; return (Errno e)
298 foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt
299 #endif
300
301 -- | Reset the current thread\'s @errno@ value to 'eOK'.
302 --
303 resetErrno :: IO ()
304
305 -- Again, setting errno has to be done via a C function.
306 #ifdef __NHC__
307 resetErrno = poke _errno 0
308 #else
309 resetErrno = set_errno 0
310 foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO ()
311 #endif
312
313 -- throw current "errno" value
314 -- ---------------------------
315
316 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'.
317 --
318 throwErrno :: String -- ^ textual description of the error location
319 -> IO a
320 throwErrno loc =
321 do
322 errno <- getErrno
323 ioError (errnoToIOError loc errno Nothing Nothing)
324
325
326 -- guards for IO operations that may fail
327 -- --------------------------------------
328
329 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
330 -- if the result value of the 'IO' action meets the given predicate.
331 --
332 throwErrnoIf :: (a -> Bool) -- ^ predicate to apply to the result value
333 -- of the 'IO' operation
334 -> String -- ^ textual description of the location
335 -> IO a -- ^ the 'IO' operation to be executed
336 -> IO a
337 throwErrnoIf pred loc f =
338 do
339 res <- f
340 if pred res then throwErrno loc else return res
341
342 -- | as 'throwErrnoIf', but discards the result of the 'IO' action after
343 -- error handling.
344 --
345 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
346 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
347
348 -- | as 'throwErrnoIf', but retry the 'IO' action when it yields the
349 -- error code 'eINTR' - this amounts to the standard retry loop for
350 -- interrupted POSIX system calls.
351 --
352 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
353 throwErrnoIfRetry pred loc f =
354 do
355 res <- f
356 if pred res
357 then do
358 err <- getErrno
359 if err == eINTR
360 then throwErrnoIfRetry pred loc f
361 else throwErrno loc
362 else return res
363
364 -- | as 'throwErrnoIfRetry', but additionally if the operation
365 -- yields the error code 'eAGAIN' or 'eWOULDBLOCK', an alternative
366 -- action is executed before retrying.
367 --
368 throwErrnoIfRetryMayBlock
369 :: (a -> Bool) -- ^ predicate to apply to the result value
370 -- of the 'IO' operation
371 -> String -- ^ textual description of the location
372 -> IO a -- ^ the 'IO' operation to be executed
373 -> IO b -- ^ action to execute before retrying if
374 -- an immediate retry would block
375 -> IO a
376 throwErrnoIfRetryMayBlock pred loc f on_block =
377 do
378 res <- f
379 if pred res
380 then do
381 err <- getErrno
382 if err == eINTR
383 then throwErrnoIfRetryMayBlock pred loc f on_block
384 else if err == eWOULDBLOCK || err == eAGAIN
385 then do _ <- on_block
386 throwErrnoIfRetryMayBlock pred loc f on_block
387 else throwErrno loc
388 else return res
389
390 -- | as 'throwErrnoIfRetry', but discards the result.
391 --
392 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
393 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
394
395 -- | as 'throwErrnoIfRetryMayBlock', but discards the result.
396 --
397 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
398 throwErrnoIfRetryMayBlock_ pred loc f on_block
399 = void $ throwErrnoIfRetryMayBlock pred loc f on_block
400
401 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
402 -- if the 'IO' action returns a result of @-1@.
403 --
404 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
405 throwErrnoIfMinus1 = throwErrnoIf (== -1)
406
407 -- | as 'throwErrnoIfMinus1', but discards the result.
408 --
409 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
410 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
411
412 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
413 -- if the 'IO' action returns a result of @-1@, but retries in case of
414 -- an interrupted operation.
415 --
416 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
417 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
418
419 -- | as 'throwErrnoIfMinus1', but discards the result.
420 --
421 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
422 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
423
424 -- | as 'throwErrnoIfMinus1Retry', but checks for operations that would block.
425 --
426 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
427 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
428
429 -- | as 'throwErrnoIfMinus1RetryMayBlock', but discards the result.
430 --
431 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
432 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
433
434 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
435 -- if the 'IO' action returns 'nullPtr'.
436 --
437 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
438 throwErrnoIfNull = throwErrnoIf (== nullPtr)
439
440 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
441 -- if the 'IO' action returns 'nullPtr',
442 -- but retry in case of an interrupted operation.
443 --
444 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
445 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
446
447 -- | as 'throwErrnoIfNullRetry', but checks for operations that would block.
448 --
449 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
450 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
451
452 -- | as 'throwErrno', but exceptions include the given path when appropriate.
453 --
454 throwErrnoPath :: String -> FilePath -> IO a
455 throwErrnoPath loc path =
456 do
457 errno <- getErrno
458 ioError (errnoToIOError loc errno Nothing (Just path))
459
460 -- | as 'throwErrnoIf', but exceptions include the given path when
461 -- appropriate.
462 --
463 throwErrnoPathIf :: (a -> Bool) -> String -> FilePath -> IO a -> IO a
464 throwErrnoPathIf pred loc path f =
465 do
466 res <- f
467 if pred res then throwErrnoPath loc path else return res
468
469 -- | as 'throwErrnoIf_', but exceptions include the given path when
470 -- appropriate.
471 --
472 throwErrnoPathIf_ :: (a -> Bool) -> String -> FilePath -> IO a -> IO ()
473 throwErrnoPathIf_ pred loc path f = void $ throwErrnoPathIf pred loc path f
474
475 -- | as 'throwErrnoIfNull', but exceptions include the given path when
476 -- appropriate.
477 --
478 throwErrnoPathIfNull :: String -> FilePath -> IO (Ptr a) -> IO (Ptr a)
479 throwErrnoPathIfNull = throwErrnoPathIf (== nullPtr)
480
481 -- | as 'throwErrnoIfMinus1', but exceptions include the given path when
482 -- appropriate.
483 --
484 throwErrnoPathIfMinus1 :: Num a => String -> FilePath -> IO a -> IO a
485 throwErrnoPathIfMinus1 = throwErrnoPathIf (== -1)
486
487 -- | as 'throwErrnoIfMinus1_', but exceptions include the given path when
488 -- appropriate.
489 --
490 throwErrnoPathIfMinus1_ :: Num a => String -> FilePath -> IO a -> IO ()
491 throwErrnoPathIfMinus1_ = throwErrnoPathIf_ (== -1)
492
493 -- conversion of an "errno" value into IO error
494 -- --------------------------------------------
495
496 -- | Construct an 'IOError' based on the given 'Errno' value.
497 -- The optional information can be used to improve the accuracy of
498 -- error messages.
499 --
500 errnoToIOError :: String -- ^ the location where the error occurred
501 -> Errno -- ^ the error number
502 -> Maybe Handle -- ^ optional handle associated with the error
503 -> Maybe String -- ^ optional filename associated with the error
504 -> IOError
505 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
506 str <- strerror errno >>= peekCString
507 #if __GLASGOW_HASKELL__
508 return (IOError maybeHdl errType loc str (Just errno') maybeName)
509 where
510 Errno errno' = errno
511 errType
512 | errno == eOK = OtherError
513 | errno == e2BIG = ResourceExhausted
514 | errno == eACCES = PermissionDenied
515 | errno == eADDRINUSE = ResourceBusy
516 | errno == eADDRNOTAVAIL = UnsupportedOperation
517 | errno == eADV = OtherError
518 | errno == eAFNOSUPPORT = UnsupportedOperation
519 | errno == eAGAIN = ResourceExhausted
520 | errno == eALREADY = AlreadyExists
521 | errno == eBADF = InvalidArgument
522 | errno == eBADMSG = InappropriateType
523 | errno == eBADRPC = OtherError
524 | errno == eBUSY = ResourceBusy
525 | errno == eCHILD = NoSuchThing
526 | errno == eCOMM = ResourceVanished
527 | errno == eCONNABORTED = OtherError
528 | errno == eCONNREFUSED = NoSuchThing
529 | errno == eCONNRESET = ResourceVanished
530 | errno == eDEADLK = ResourceBusy
531 | errno == eDESTADDRREQ = InvalidArgument
532 | errno == eDIRTY = UnsatisfiedConstraints
533 | errno == eDOM = InvalidArgument
534 | errno == eDQUOT = PermissionDenied
535 | errno == eEXIST = AlreadyExists
536 | errno == eFAULT = OtherError
537 | errno == eFBIG = PermissionDenied
538 | errno == eFTYPE = InappropriateType
539 | errno == eHOSTDOWN = NoSuchThing
540 | errno == eHOSTUNREACH = NoSuchThing
541 | errno == eIDRM = ResourceVanished
542 | errno == eILSEQ = InvalidArgument
543 | errno == eINPROGRESS = AlreadyExists
544 | errno == eINTR = Interrupted
545 | errno == eINVAL = InvalidArgument
546 | errno == eIO = HardwareFault
547 | errno == eISCONN = AlreadyExists
548 | errno == eISDIR = InappropriateType
549 | errno == eLOOP = InvalidArgument
550 | errno == eMFILE = ResourceExhausted
551 | errno == eMLINK = ResourceExhausted
552 | errno == eMSGSIZE = ResourceExhausted
553 | errno == eMULTIHOP = UnsupportedOperation
554 | errno == eNAMETOOLONG = InvalidArgument
555 | errno == eNETDOWN = ResourceVanished
556 | errno == eNETRESET = ResourceVanished
557 | errno == eNETUNREACH = NoSuchThing
558 | errno == eNFILE = ResourceExhausted
559 | errno == eNOBUFS = ResourceExhausted
560 | errno == eNODATA = NoSuchThing
561 | errno == eNODEV = UnsupportedOperation
562 | errno == eNOENT = NoSuchThing
563 | errno == eNOEXEC = InvalidArgument
564 | errno == eNOLCK = ResourceExhausted
565 | errno == eNOLINK = ResourceVanished
566 | errno == eNOMEM = ResourceExhausted
567 | errno == eNOMSG = NoSuchThing
568 | errno == eNONET = NoSuchThing
569 | errno == eNOPROTOOPT = UnsupportedOperation
570 | errno == eNOSPC = ResourceExhausted
571 | errno == eNOSR = ResourceExhausted
572 | errno == eNOSTR = InvalidArgument
573 | errno == eNOSYS = UnsupportedOperation
574 | errno == eNOTBLK = InvalidArgument
575 | errno == eNOTCONN = InvalidArgument
576 | errno == eNOTDIR = InappropriateType
577 | errno == eNOTEMPTY = UnsatisfiedConstraints
578 | errno == eNOTSOCK = InvalidArgument
579 | errno == eNOTTY = IllegalOperation
580 | errno == eNXIO = NoSuchThing
581 | errno == eOPNOTSUPP = UnsupportedOperation
582 | errno == ePERM = PermissionDenied
583 | errno == ePFNOSUPPORT = UnsupportedOperation
584 | errno == ePIPE = ResourceVanished
585 | errno == ePROCLIM = PermissionDenied
586 | errno == ePROCUNAVAIL = UnsupportedOperation
587 | errno == ePROGMISMATCH = ProtocolError
588 | errno == ePROGUNAVAIL = UnsupportedOperation
589 | errno == ePROTO = ProtocolError
590 | errno == ePROTONOSUPPORT = ProtocolError
591 | errno == ePROTOTYPE = ProtocolError
592 | errno == eRANGE = UnsupportedOperation
593 | errno == eREMCHG = ResourceVanished
594 | errno == eREMOTE = IllegalOperation
595 | errno == eROFS = PermissionDenied
596 | errno == eRPCMISMATCH = ProtocolError
597 | errno == eRREMOTE = IllegalOperation
598 | errno == eSHUTDOWN = IllegalOperation
599 | errno == eSOCKTNOSUPPORT = UnsupportedOperation
600 | errno == eSPIPE = UnsupportedOperation
601 | errno == eSRCH = NoSuchThing
602 | errno == eSRMNT = UnsatisfiedConstraints
603 | errno == eSTALE = ResourceVanished
604 | errno == eTIME = TimeExpired
605 | errno == eTIMEDOUT = TimeExpired
606 | errno == eTOOMANYREFS = ResourceExhausted
607 | errno == eTXTBSY = ResourceBusy
608 | errno == eUSERS = ResourceExhausted
609 | errno == eWOULDBLOCK = OtherError
610 | errno == eXDEV = UnsupportedOperation
611 | otherwise = OtherError
612 #else
613 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
614 #endif
615
616 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)