1 % -----------------------------------------------------------------------------
2 % $Id: PrelCError.lhs,v 1.4 2001/01/16 06:02:29 qrczak Exp $
4 % (c) The FFI task force, 2000
7 C-specific Marshalling support: Handling of C "errno" error codes
10 {-# OPTIONS -fno-implicit-prelude #-}
12 -- this is were we get the CCONST_XXX definitions from that configure
19 -- Haskell representation for "errno" values
21 Errno(..), -- instance: Eq
22 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
23 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
24 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
25 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
26 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
27 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
28 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
29 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
30 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
31 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
32 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
33 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
34 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
35 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
37 isValidErrno, -- :: Errno -> Bool
39 -- access to the current thread's "errno" value
41 getErrno, -- :: IO Errno
42 resetErrno, -- :: IO ()
44 -- conversion of an "errno" value into IO error
46 errnoToIOError, -- :: String -- location
48 -- -> Maybe Handle -- handle
49 -- -> Maybe String -- filename
52 -- throw current "errno" value
54 throwErrno, -- :: String -> IO a
56 -- guards for IO operations that may fail
58 throwErrnoIf, -- :: (a -> Bool) -> String -> IO a -> IO a
59 throwErrnoIf_, -- :: (a -> Bool) -> String -> IO a -> IO ()
60 throwErrnoIfRetry, -- :: (a -> Bool) -> String -> IO a -> IO a
61 throwErrnoIfRetry_, -- :: (a -> Bool) -> String -> IO a -> IO ()
62 throwErrnoIfMinus1, -- :: Num a
63 -- => String -> IO a -> IO a
64 throwErrnoIfMinus1_, -- :: Num a
65 -- => String -> IO a -> IO ()
66 throwErrnoIfMinus1Retry,
68 -- => String -> IO a -> IO a
69 throwErrnoIfMinus1Retry_,
71 -- => String -> IO a -> IO ()
72 throwErrnoIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
73 throwErrnoIfNullRetry -- :: String -> IO (Ptr a) -> IO (Ptr a)
77 -- system dependent imports
78 -- ------------------------
80 -- GHC allows us to get at the guts inside IO errors/exceptions
82 #if __GLASGOW_HASKELL__
83 #if __GLASGOW_HASKELL__ < 409
84 import PrelIOBase (IOError(..), IOErrorType(..))
86 import PrelIOBase (Exception(..), IOException(..), IOErrorType(..))
88 #endif /* __GLASGOW_HASKELL__ */
96 #if __GLASGOW_HASKELL__
98 import PrelMarshalError
107 import Ptr (Ptr, nullPtr)
109 import MarshalError (void)
111 import IO (IOError, Handle, ioError)
114 -- system dependent re-definitions
115 -- -------------------------------
117 -- we bring GHC's `IOErrorType' in scope in other compilers to simplify the
118 -- routine `errnoToIOError' below
120 #if !__GLASGOW_HASKELL__
122 = AlreadyExists | HardwareFault
123 | IllegalOperation | InappropriateType
124 | Interrupted | InvalidArgument
125 | NoSuchThing | OtherError
126 | PermissionDenied | ProtocolError
127 | ResourceBusy | ResourceExhausted
128 | ResourceVanished | SystemError
129 | TimeExpired | UnsatisfiedConstraints
130 | UnsupportedOperation
138 -- Haskell representation for "errno" values
140 newtype Errno = Errno CInt
142 instance Eq Errno where
143 errno1@(Errno no1) == errno2@(Errno no2)
144 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
147 -- common "errno" symbols
149 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
150 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
151 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
152 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
153 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
154 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
155 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
156 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
157 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
158 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
159 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
160 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
161 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
162 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV :: Errno
164 -- the CCONST_XXX identifiers are cpp symbols whose value is computed by
168 e2BIG = Errno (CCONST_E2BIG)
169 eACCES = Errno (CCONST_EACCES)
170 eADDRINUSE = Errno (CCONST_EADDRINUSE)
171 eADDRNOTAVAIL = Errno (CCONST_EADDRNOTAVAIL)
172 eADV = Errno (CCONST_EADV)
173 eAFNOSUPPORT = Errno (CCONST_EAFNOSUPPORT)
174 eAGAIN = Errno (CCONST_EAGAIN)
175 eALREADY = Errno (CCONST_EALREADY)
176 eBADF = Errno (CCONST_EBADF)
177 eBADMSG = Errno (CCONST_EBADMSG)
178 eBADRPC = Errno (CCONST_EBADRPC)
179 eBUSY = Errno (CCONST_EBUSY)
180 eCHILD = Errno (CCONST_ECHILD)
181 eCOMM = Errno (CCONST_ECOMM)
182 eCONNABORTED = Errno (CCONST_ECONNABORTED)
183 eCONNREFUSED = Errno (CCONST_ECONNREFUSED)
184 eCONNRESET = Errno (CCONST_ECONNRESET)
185 eDEADLK = Errno (CCONST_EDEADLK)
186 eDESTADDRREQ = Errno (CCONST_EDESTADDRREQ)
187 eDIRTY = Errno (CCONST_EDIRTY)
188 eDOM = Errno (CCONST_EDOM)
189 eDQUOT = Errno (CCONST_EDQUOT)
190 eEXIST = Errno (CCONST_EEXIST)
191 eFAULT = Errno (CCONST_EFAULT)
192 eFBIG = Errno (CCONST_EFBIG)
193 eFTYPE = Errno (CCONST_EFTYPE)
194 eHOSTDOWN = Errno (CCONST_EHOSTDOWN)
195 eHOSTUNREACH = Errno (CCONST_EHOSTUNREACH)
196 eIDRM = Errno (CCONST_EIDRM)
197 eILSEQ = Errno (CCONST_EILSEQ)
198 eINPROGRESS = Errno (CCONST_EINPROGRESS)
199 eINTR = Errno (CCONST_EINTR)
200 eINVAL = Errno (CCONST_EINVAL)
201 eIO = Errno (CCONST_EIO)
202 eISCONN = Errno (CCONST_EISCONN)
203 eISDIR = Errno (CCONST_EISDIR)
204 eLOOP = Errno (CCONST_ELOOP)
205 eMFILE = Errno (CCONST_EMFILE)
206 eMLINK = Errno (CCONST_EMLINK)
207 eMSGSIZE = Errno (CCONST_EMSGSIZE)
208 eMULTIHOP = Errno (CCONST_EMULTIHOP)
209 eNAMETOOLONG = Errno (CCONST_ENAMETOOLONG)
210 eNETDOWN = Errno (CCONST_ENETDOWN)
211 eNETRESET = Errno (CCONST_ENETRESET)
212 eNETUNREACH = Errno (CCONST_ENETUNREACH)
213 eNFILE = Errno (CCONST_ENFILE)
214 eNOBUFS = Errno (CCONST_ENOBUFS)
215 eNODATA = Errno (CCONST_ENODATA)
216 eNODEV = Errno (CCONST_ENODEV)
217 eNOENT = Errno (CCONST_ENOENT)
218 eNOEXEC = Errno (CCONST_ENOEXEC)
219 eNOLCK = Errno (CCONST_ENOLCK)
220 eNOLINK = Errno (CCONST_ENOLINK)
221 eNOMEM = Errno (CCONST_ENOMEM)
222 eNOMSG = Errno (CCONST_ENOMSG)
223 eNONET = Errno (CCONST_ENONET)
224 eNOPROTOOPT = Errno (CCONST_ENOPROTOOPT)
225 eNOSPC = Errno (CCONST_ENOSPC)
226 eNOSR = Errno (CCONST_ENOSR)
227 eNOSTR = Errno (CCONST_ENOSTR)
228 eNOSYS = Errno (CCONST_ENOSYS)
229 eNOTBLK = Errno (CCONST_ENOTBLK)
230 eNOTCONN = Errno (CCONST_ENOTCONN)
231 eNOTDIR = Errno (CCONST_ENOTDIR)
232 eNOTEMPTY = Errno (CCONST_ENOTEMPTY)
233 eNOTSOCK = Errno (CCONST_ENOTSOCK)
234 eNOTTY = Errno (CCONST_ENOTTY)
235 eNXIO = Errno (CCONST_ENXIO)
236 eOPNOTSUPP = Errno (CCONST_EOPNOTSUPP)
237 ePERM = Errno (CCONST_EPERM)
238 ePFNOSUPPORT = Errno (CCONST_EPFNOSUPPORT)
239 ePIPE = Errno (CCONST_EPIPE)
240 ePROCLIM = Errno (CCONST_EPROCLIM)
241 ePROCUNAVAIL = Errno (CCONST_EPROCUNAVAIL)
242 ePROGMISMATCH = Errno (CCONST_EPROGMISMATCH)
243 ePROGUNAVAIL = Errno (CCONST_EPROGUNAVAIL)
244 ePROTO = Errno (CCONST_EPROTO)
245 ePROTONOSUPPORT = Errno (CCONST_EPROTONOSUPPORT)
246 ePROTOTYPE = Errno (CCONST_EPROTOTYPE)
247 eRANGE = Errno (CCONST_ERANGE)
248 eREMCHG = Errno (CCONST_EREMCHG)
249 eREMOTE = Errno (CCONST_EREMOTE)
250 eROFS = Errno (CCONST_EROFS)
251 eRPCMISMATCH = Errno (CCONST_ERPCMISMATCH)
252 eRREMOTE = Errno (CCONST_ERREMOTE)
253 eSHUTDOWN = Errno (CCONST_ESHUTDOWN)
254 eSOCKTNOSUPPORT = Errno (CCONST_ESOCKTNOSUPPORT)
255 eSPIPE = Errno (CCONST_ESPIPE)
256 eSRCH = Errno (CCONST_ESRCH)
257 eSRMNT = Errno (CCONST_ESRMNT)
258 eSTALE = Errno (CCONST_ESTALE)
259 eTIME = Errno (CCONST_ETIME)
260 eTIMEDOUT = Errno (CCONST_ETIMEDOUT)
261 eTOOMANYREFS = Errno (CCONST_ETOOMANYREFS)
262 eTXTBSY = Errno (CCONST_ETXTBSY)
263 eUSERS = Errno (CCONST_EUSERS)
264 eWOULDBLOCK = Errno (CCONST_EWOULDBLOCK)
265 eXDEV = Errno (CCONST_EXDEV)
267 -- checks whether the given errno value is supported on the current
270 isValidErrno :: Errno -> Bool
272 -- the configure script sets all invalid "errno"s to -1
274 isValidErrno (Errno errno) = errno /= -1
277 -- access to the current thread's "errno" value
278 -- --------------------------------------------
280 -- yield the current thread's "errno" value
283 getErrno = liftM Errno (peek _errno)
286 -- set the current thread's "errno" value to 0
289 resetErrno = poke _errno 0
292 -- throw current "errno" value
293 -- ---------------------------
295 -- the common case: throw an IO error based on a textual description
296 -- of the error location and the current thread's "errno" value
298 throwErrno :: String -> IO a
302 ioError (errnoToIOError loc errno Nothing Nothing)
305 -- guards for IO operations that may fail
306 -- --------------------------------------
308 -- guard an IO operation and throw an "errno" based exception of the result
309 -- value of the IO operation meets the given predicate
311 throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a
312 throwErrnoIf pred loc f =
315 if pred res then throwErrno loc else return res
317 -- as `throwErrnoIf', but discards the result
319 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
320 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
322 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
325 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
326 throwErrnoIfRetry pred loc f =
333 then throwErrnoIfRetry pred loc f
337 -- as `throwErrnoIfRetry', but discards the result
339 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
340 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
342 -- throws "errno" if a result of "-1" is returned
344 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
345 throwErrnoIfMinus1 = throwErrnoIf (== -1)
347 -- as `throwErrnoIfMinus1', but discards the result
349 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
350 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
352 -- throws "errno" if a result of "-1" is returned, but retries in case of an
353 -- interrupted operation
355 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
356 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
358 -- as `throwErrnoIfMinus1', but discards the result
360 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
361 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
363 -- throws "errno" if a result of a NULL pointer is returned
365 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
366 throwErrnoIfNull = throwErrnoIf (== nullPtr)
368 -- throws "errno" if a result of a NULL pointer is returned, but retries in
369 -- case of an interrupted operation
371 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
372 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
375 -- conversion of an "errno" value into IO error
376 -- --------------------------------------------
378 -- convert a location string, an "errno" value, an optional handle,
379 -- and an optional filename into a matching IO error
381 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
382 errnoToIOError loc errno@(Errno no) maybeHdl maybeName =
383 #if __GLASGOW_HASKELL__
384 IOException (IOError maybeHdl errType loc str maybeName)
386 userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName)
390 | errno == eOK = (OtherError,
392 | errno == e2BIG = (ResourceExhausted,
393 "argument list too long")
394 | errno == eACCES = (PermissionDenied,
395 "inadequate access permission")
396 | errno == eADDRINUSE = (ResourceBusy,
397 "address already in use")
398 | errno == eADDRNOTAVAIL = (UnsupportedOperation,
399 "address not available")
400 | errno == eADV = (OtherError,
401 "RFS advertise error")
402 | errno == eAFNOSUPPORT = (UnsupportedOperation,
403 "address family not supported by " ++
405 -- no multiline strings with cpp
406 | errno == eAGAIN = (ResourceExhausted,
407 "insufficient resources")
408 | errno == eALREADY = (AlreadyExists,
409 "operation already in progress")
410 | errno == eBADF = (OtherError,
411 "internal error (EBADF)")
412 | errno == eBADMSG = (InappropriateType,
413 "next message has wrong type")
414 | errno == eBADRPC = (OtherError,
415 "invalid RPC request or response")
416 | errno == eBUSY = (ResourceBusy,
418 | errno == eCHILD = (NoSuchThing,
419 "no child processes")
420 | errno == eCOMM = (ResourceVanished,
421 "no virtual circuit could be found")
422 | errno == eCONNABORTED = (OtherError,
423 "aborted connection")
424 | errno == eCONNREFUSED = (NoSuchThing,
425 "no listener on remote host")
426 | errno == eCONNRESET = (ResourceVanished,
427 "connection reset by peer")
428 | errno == eDEADLK = (ResourceBusy,
429 "resource deadlock avoided")
430 | errno == eDESTADDRREQ = (InvalidArgument,
431 "destination address required")
432 | errno == eDIRTY = (UnsatisfiedConstraints,
434 | errno == eDOM = (InvalidArgument,
435 "argument too large")
436 | errno == eDQUOT = (PermissionDenied,
438 | errno == eEXIST = (AlreadyExists,
439 "file already exists")
440 | errno == eFAULT = (OtherError,
441 "internal error (EFAULT)")
442 | errno == eFBIG = (PermissionDenied,
444 | errno == eFTYPE = (InappropriateType,
445 "inappropriate NFS file type or format")
446 | errno == eHOSTDOWN = (NoSuchThing,
447 "destination host down")
448 | errno == eHOSTUNREACH = (NoSuchThing,
449 "remote host is unreachable")
450 | errno == eIDRM = (ResourceVanished,
451 "IPC identifier removed")
452 | errno == eILSEQ = (InvalidArgument,
453 "invalid wide character")
454 | errno == eINPROGRESS = (AlreadyExists,
455 "operation now in progress")
456 | errno == eINTR = (Interrupted,
457 "interrupted system call")
458 | errno == eINVAL = (InvalidArgument,
460 | errno == eIO = (HardwareFault,
462 | errno == eISCONN = (AlreadyExists,
463 "socket is already connected")
464 | errno == eISDIR = (InappropriateType,
465 "file is a directory")
466 | errno == eLOOP = (InvalidArgument,
467 "too many symbolic links")
468 | errno == eMFILE = (ResourceExhausted,
469 "process file table full")
470 | errno == eMLINK = (ResourceExhausted,
472 | errno == eMSGSIZE = (ResourceExhausted,
474 | errno == eMULTIHOP = (UnsupportedOperation,
475 "multi-hop RFS request")
476 | errno == eNAMETOOLONG = (InvalidArgument,
478 | errno == eNETDOWN = (ResourceVanished,
480 | errno == eNETRESET = (ResourceVanished,
481 "remote host rebooted; connection lost")
482 | errno == eNETUNREACH = (NoSuchThing,
483 "remote network is unreachable")
484 | errno == eNFILE = (ResourceExhausted,
485 "system file table full")
486 | errno == eNOBUFS = (ResourceExhausted,
487 "no buffer space available")
488 | errno == eNODATA = (NoSuchThing,
489 "no message on the stream head read " ++
491 -- no multiline strings with cpp
492 | errno == eNODEV = (NoSuchThing,
494 | errno == eNOENT = (NoSuchThing,
495 "no such file or directory")
496 | errno == eNOEXEC = (InvalidArgument,
497 "not an executable file")
498 | errno == eNOLCK = (ResourceExhausted,
499 "no file locks available")
500 | errno == eNOLINK = (ResourceVanished,
501 "RFS link has been severed")
502 | errno == eNOMEM = (ResourceExhausted,
503 "not enough virtual memory")
504 | errno == eNOMSG = (NoSuchThing,
505 "no message of desired type")
506 | errno == eNONET = (NoSuchThing,
507 "host is not on a network")
508 | errno == eNOPROTOOPT = (UnsupportedOperation,
509 "operation not supported by protocol")
510 | errno == eNOSPC = (ResourceExhausted,
511 "no space left on device")
512 | errno == eNOSR = (ResourceExhausted,
513 "out of stream resources")
514 | errno == eNOSTR = (InvalidArgument,
515 "not a stream device")
516 | errno == eNOSYS = (UnsupportedOperation,
517 "function not implemented")
518 | errno == eNOTBLK = (InvalidArgument,
519 "not a block device")
520 | errno == eNOTCONN = (InvalidArgument,
521 "socket is not connected")
522 | errno == eNOTDIR = (InappropriateType,
524 | errno == eNOTEMPTY = (UnsatisfiedConstraints,
525 "directory not empty")
526 | errno == eNOTSOCK = (InvalidArgument,
528 | errno == eNOTTY = (IllegalOperation,
529 "inappropriate ioctl for device")
530 | errno == eNXIO = (NoSuchThing,
531 "no such device or address")
532 | errno == eOPNOTSUPP = (UnsupportedOperation,
533 "operation not supported on socket")
534 | errno == ePERM = (PermissionDenied,
535 "privileged operation")
536 | errno == ePFNOSUPPORT = (UnsupportedOperation,
537 "protocol family not supported")
538 | errno == ePIPE = (ResourceVanished,
540 | errno == ePROCLIM = (PermissionDenied,
541 "too many processes")
542 | errno == ePROCUNAVAIL = (UnsupportedOperation,
543 "unimplemented RPC procedure")
544 | errno == ePROGMISMATCH = (ProtocolError,
545 "unsupported RPC program version")
546 | errno == ePROGUNAVAIL = (UnsupportedOperation,
547 "RPC program unavailable")
548 | errno == ePROTO = (ProtocolError,
549 "error in streams protocol")
550 | errno == ePROTONOSUPPORT = (ProtocolError,
551 "protocol not supported")
552 | errno == ePROTOTYPE = (ProtocolError,
553 "wrong protocol for socket")
554 | errno == eRANGE = (UnsupportedOperation,
556 | errno == eREMCHG = (ResourceVanished,
557 "remote address changed")
558 | errno == eREMOTE = (IllegalOperation,
559 "too many levels of remote in path")
560 | errno == eROFS = (PermissionDenied,
561 "read-only file system")
562 | errno == eRPCMISMATCH = (ProtocolError,
563 "RPC version is wrong")
564 | errno == eRREMOTE = (IllegalOperation,
566 | errno == eSHUTDOWN = (IllegalOperation,
567 "can't send after socket shutdown")
568 | errno == eSOCKTNOSUPPORT = (UnsupportedOperation,
569 "socket type not supported")
570 | errno == eSPIPE = (UnsupportedOperation,
571 "can't seek on a pipe")
572 | errno == eSRCH = (NoSuchThing,
574 | errno == eSRMNT = (UnsatisfiedConstraints,
575 "RFS resources still mounted by " ++
577 -- no multiline strings with cpp
578 | errno == eSTALE = (ResourceVanished,
579 "stale NFS file handle")
580 | errno == eTIME = (TimeExpired,
582 | errno == eTIMEDOUT = (TimeExpired,
583 "connection timed out")
584 | errno == eTOOMANYREFS = (ResourceExhausted,
585 "too many references; can't splice")
586 | errno == eTXTBSY = (ResourceBusy,
588 | errno == eUSERS = (ResourceExhausted,
590 | errno == eWOULDBLOCK = (OtherError,
591 "operation would block")
592 | errno == eXDEV = (UnsupportedOperation,
593 "can't make a cross-device link")
594 | otherwise = (OtherError,
595 "unexpected error (error code: "
598 foreign label "errno" _errno :: Ptr CInt
599 -- FIXME: this routine should eventually be provided by the Haskell runtime
600 -- and guarantee that the "errno" of the last operation performed by
601 -- the current thread is returned