1 % -----------------------------------------------------------------------------
2 % $Id: PrelCError.lhs,v 1.6 2001/01/27 07:46:27 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 -#include "cbits/ghc_errno.h" #-}
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 -- import of C function that gives address of errno
140 foreign import "ghcErrno" unsafe _errno :: Ptr CInt
142 -- Haskell representation for "errno" values
144 newtype Errno = Errno CInt
146 instance Eq Errno where
147 errno1@(Errno no1) == errno2@(Errno no2)
148 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
151 -- common "errno" symbols
153 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
154 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
155 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
156 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
157 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
158 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
159 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
160 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
161 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
162 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
163 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
164 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
165 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
166 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV :: Errno
168 -- the CCONST_XXX identifiers are cpp symbols whose value is computed by
172 e2BIG = Errno (CCONST_E2BIG)
173 eACCES = Errno (CCONST_EACCES)
174 eADDRINUSE = Errno (CCONST_EADDRINUSE)
175 eADDRNOTAVAIL = Errno (CCONST_EADDRNOTAVAIL)
176 eADV = Errno (CCONST_EADV)
177 eAFNOSUPPORT = Errno (CCONST_EAFNOSUPPORT)
178 eAGAIN = Errno (CCONST_EAGAIN)
179 eALREADY = Errno (CCONST_EALREADY)
180 eBADF = Errno (CCONST_EBADF)
181 eBADMSG = Errno (CCONST_EBADMSG)
182 eBADRPC = Errno (CCONST_EBADRPC)
183 eBUSY = Errno (CCONST_EBUSY)
184 eCHILD = Errno (CCONST_ECHILD)
185 eCOMM = Errno (CCONST_ECOMM)
186 eCONNABORTED = Errno (CCONST_ECONNABORTED)
187 eCONNREFUSED = Errno (CCONST_ECONNREFUSED)
188 eCONNRESET = Errno (CCONST_ECONNRESET)
189 eDEADLK = Errno (CCONST_EDEADLK)
190 eDESTADDRREQ = Errno (CCONST_EDESTADDRREQ)
191 eDIRTY = Errno (CCONST_EDIRTY)
192 eDOM = Errno (CCONST_EDOM)
193 eDQUOT = Errno (CCONST_EDQUOT)
194 eEXIST = Errno (CCONST_EEXIST)
195 eFAULT = Errno (CCONST_EFAULT)
196 eFBIG = Errno (CCONST_EFBIG)
197 eFTYPE = Errno (CCONST_EFTYPE)
198 eHOSTDOWN = Errno (CCONST_EHOSTDOWN)
199 eHOSTUNREACH = Errno (CCONST_EHOSTUNREACH)
200 eIDRM = Errno (CCONST_EIDRM)
201 eILSEQ = Errno (CCONST_EILSEQ)
202 eINPROGRESS = Errno (CCONST_EINPROGRESS)
203 eINTR = Errno (CCONST_EINTR)
204 eINVAL = Errno (CCONST_EINVAL)
205 eIO = Errno (CCONST_EIO)
206 eISCONN = Errno (CCONST_EISCONN)
207 eISDIR = Errno (CCONST_EISDIR)
208 eLOOP = Errno (CCONST_ELOOP)
209 eMFILE = Errno (CCONST_EMFILE)
210 eMLINK = Errno (CCONST_EMLINK)
211 eMSGSIZE = Errno (CCONST_EMSGSIZE)
212 eMULTIHOP = Errno (CCONST_EMULTIHOP)
213 eNAMETOOLONG = Errno (CCONST_ENAMETOOLONG)
214 eNETDOWN = Errno (CCONST_ENETDOWN)
215 eNETRESET = Errno (CCONST_ENETRESET)
216 eNETUNREACH = Errno (CCONST_ENETUNREACH)
217 eNFILE = Errno (CCONST_ENFILE)
218 eNOBUFS = Errno (CCONST_ENOBUFS)
219 eNODATA = Errno (CCONST_ENODATA)
220 eNODEV = Errno (CCONST_ENODEV)
221 eNOENT = Errno (CCONST_ENOENT)
222 eNOEXEC = Errno (CCONST_ENOEXEC)
223 eNOLCK = Errno (CCONST_ENOLCK)
224 eNOLINK = Errno (CCONST_ENOLINK)
225 eNOMEM = Errno (CCONST_ENOMEM)
226 eNOMSG = Errno (CCONST_ENOMSG)
227 eNONET = Errno (CCONST_ENONET)
228 eNOPROTOOPT = Errno (CCONST_ENOPROTOOPT)
229 eNOSPC = Errno (CCONST_ENOSPC)
230 eNOSR = Errno (CCONST_ENOSR)
231 eNOSTR = Errno (CCONST_ENOSTR)
232 eNOSYS = Errno (CCONST_ENOSYS)
233 eNOTBLK = Errno (CCONST_ENOTBLK)
234 eNOTCONN = Errno (CCONST_ENOTCONN)
235 eNOTDIR = Errno (CCONST_ENOTDIR)
236 eNOTEMPTY = Errno (CCONST_ENOTEMPTY)
237 eNOTSOCK = Errno (CCONST_ENOTSOCK)
238 eNOTTY = Errno (CCONST_ENOTTY)
239 eNXIO = Errno (CCONST_ENXIO)
240 eOPNOTSUPP = Errno (CCONST_EOPNOTSUPP)
241 ePERM = Errno (CCONST_EPERM)
242 ePFNOSUPPORT = Errno (CCONST_EPFNOSUPPORT)
243 ePIPE = Errno (CCONST_EPIPE)
244 ePROCLIM = Errno (CCONST_EPROCLIM)
245 ePROCUNAVAIL = Errno (CCONST_EPROCUNAVAIL)
246 ePROGMISMATCH = Errno (CCONST_EPROGMISMATCH)
247 ePROGUNAVAIL = Errno (CCONST_EPROGUNAVAIL)
248 ePROTO = Errno (CCONST_EPROTO)
249 ePROTONOSUPPORT = Errno (CCONST_EPROTONOSUPPORT)
250 ePROTOTYPE = Errno (CCONST_EPROTOTYPE)
251 eRANGE = Errno (CCONST_ERANGE)
252 eREMCHG = Errno (CCONST_EREMCHG)
253 eREMOTE = Errno (CCONST_EREMOTE)
254 eROFS = Errno (CCONST_EROFS)
255 eRPCMISMATCH = Errno (CCONST_ERPCMISMATCH)
256 eRREMOTE = Errno (CCONST_ERREMOTE)
257 eSHUTDOWN = Errno (CCONST_ESHUTDOWN)
258 eSOCKTNOSUPPORT = Errno (CCONST_ESOCKTNOSUPPORT)
259 eSPIPE = Errno (CCONST_ESPIPE)
260 eSRCH = Errno (CCONST_ESRCH)
261 eSRMNT = Errno (CCONST_ESRMNT)
262 eSTALE = Errno (CCONST_ESTALE)
263 eTIME = Errno (CCONST_ETIME)
264 eTIMEDOUT = Errno (CCONST_ETIMEDOUT)
265 eTOOMANYREFS = Errno (CCONST_ETOOMANYREFS)
266 eTXTBSY = Errno (CCONST_ETXTBSY)
267 eUSERS = Errno (CCONST_EUSERS)
268 eWOULDBLOCK = Errno (CCONST_EWOULDBLOCK)
269 eXDEV = Errno (CCONST_EXDEV)
271 -- checks whether the given errno value is supported on the current
274 isValidErrno :: Errno -> Bool
276 -- the configure script sets all invalid "errno"s to -1
278 isValidErrno (Errno errno) = errno /= -1
281 -- access to the current thread's "errno" value
282 -- --------------------------------------------
284 -- yield the current thread's "errno" value
287 getErrno = liftM Errno (peek _errno)
290 -- set the current thread's "errno" value to 0
293 resetErrno = poke _errno 0
296 -- throw current "errno" value
297 -- ---------------------------
299 -- the common case: throw an IO error based on a textual description
300 -- of the error location and the current thread's "errno" value
302 throwErrno :: String -> IO a
306 ioError (errnoToIOError loc errno Nothing Nothing)
309 -- guards for IO operations that may fail
310 -- --------------------------------------
312 -- guard an IO operation and throw an "errno" based exception of the result
313 -- value of the IO operation meets the given predicate
315 throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a
316 throwErrnoIf pred loc f =
319 if pred res then throwErrno loc else return res
321 -- as `throwErrnoIf', but discards the result
323 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
324 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
326 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
329 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
330 throwErrnoIfRetry pred loc f =
337 then throwErrnoIfRetry pred loc f
341 -- as `throwErrnoIfRetry', but discards the result
343 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
344 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
346 -- throws "errno" if a result of "-1" is returned
348 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
349 throwErrnoIfMinus1 = throwErrnoIf (== -1)
351 -- as `throwErrnoIfMinus1', but discards the result
353 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
354 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
356 -- throws "errno" if a result of "-1" is returned, but retries in case of an
357 -- interrupted operation
359 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
360 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
362 -- as `throwErrnoIfMinus1', but discards the result
364 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
365 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
367 -- throws "errno" if a result of a NULL pointer is returned
369 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
370 throwErrnoIfNull = throwErrnoIf (== nullPtr)
372 -- throws "errno" if a result of a NULL pointer is returned, but retries in
373 -- case of an interrupted operation
375 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
376 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
379 -- conversion of an "errno" value into IO error
380 -- --------------------------------------------
382 -- convert a location string, an "errno" value, an optional handle,
383 -- and an optional filename into a matching IO error
385 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
386 errnoToIOError loc errno@(Errno no) maybeHdl maybeName =
387 #if __GLASGOW_HASKELL__
388 IOException (IOError maybeHdl errType loc str maybeName)
390 userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName)
394 | errno == eOK = (OtherError,
396 | errno == e2BIG = (ResourceExhausted,
397 "argument list too long")
398 | errno == eACCES = (PermissionDenied,
399 "inadequate access permission")
400 | errno == eADDRINUSE = (ResourceBusy,
401 "address already in use")
402 | errno == eADDRNOTAVAIL = (UnsupportedOperation,
403 "address not available")
404 | errno == eADV = (OtherError,
405 "RFS advertise error")
406 | errno == eAFNOSUPPORT = (UnsupportedOperation,
407 "address family not supported by " ++
409 -- no multiline strings with cpp
410 | errno == eAGAIN = (ResourceExhausted,
411 "insufficient resources")
412 | errno == eALREADY = (AlreadyExists,
413 "operation already in progress")
414 | errno == eBADF = (OtherError,
415 "internal error (EBADF)")
416 | errno == eBADMSG = (InappropriateType,
417 "next message has wrong type")
418 | errno == eBADRPC = (OtherError,
419 "invalid RPC request or response")
420 | errno == eBUSY = (ResourceBusy,
422 | errno == eCHILD = (NoSuchThing,
423 "no child processes")
424 | errno == eCOMM = (ResourceVanished,
425 "no virtual circuit could be found")
426 | errno == eCONNABORTED = (OtherError,
427 "aborted connection")
428 | errno == eCONNREFUSED = (NoSuchThing,
429 "no listener on remote host")
430 | errno == eCONNRESET = (ResourceVanished,
431 "connection reset by peer")
432 | errno == eDEADLK = (ResourceBusy,
433 "resource deadlock avoided")
434 | errno == eDESTADDRREQ = (InvalidArgument,
435 "destination address required")
436 | errno == eDIRTY = (UnsatisfiedConstraints,
438 | errno == eDOM = (InvalidArgument,
439 "argument too large")
440 | errno == eDQUOT = (PermissionDenied,
442 | errno == eEXIST = (AlreadyExists,
443 "file already exists")
444 | errno == eFAULT = (OtherError,
445 "internal error (EFAULT)")
446 | errno == eFBIG = (PermissionDenied,
448 | errno == eFTYPE = (InappropriateType,
449 "inappropriate NFS file type or format")
450 | errno == eHOSTDOWN = (NoSuchThing,
451 "destination host down")
452 | errno == eHOSTUNREACH = (NoSuchThing,
453 "remote host is unreachable")
454 | errno == eIDRM = (ResourceVanished,
455 "IPC identifier removed")
456 | errno == eILSEQ = (InvalidArgument,
457 "invalid wide character")
458 | errno == eINPROGRESS = (AlreadyExists,
459 "operation now in progress")
460 | errno == eINTR = (Interrupted,
461 "interrupted system call")
462 | errno == eINVAL = (InvalidArgument,
464 | errno == eIO = (HardwareFault,
466 | errno == eISCONN = (AlreadyExists,
467 "socket is already connected")
468 | errno == eISDIR = (InappropriateType,
469 "file is a directory")
470 | errno == eLOOP = (InvalidArgument,
471 "too many symbolic links")
472 | errno == eMFILE = (ResourceExhausted,
473 "process file table full")
474 | errno == eMLINK = (ResourceExhausted,
476 | errno == eMSGSIZE = (ResourceExhausted,
478 | errno == eMULTIHOP = (UnsupportedOperation,
479 "multi-hop RFS request")
480 | errno == eNAMETOOLONG = (InvalidArgument,
482 | errno == eNETDOWN = (ResourceVanished,
484 | errno == eNETRESET = (ResourceVanished,
485 "remote host rebooted; connection lost")
486 | errno == eNETUNREACH = (NoSuchThing,
487 "remote network is unreachable")
488 | errno == eNFILE = (ResourceExhausted,
489 "system file table full")
490 | errno == eNOBUFS = (ResourceExhausted,
491 "no buffer space available")
492 | errno == eNODATA = (NoSuchThing,
493 "no message on the stream head read " ++
495 -- no multiline strings with cpp
496 | errno == eNODEV = (NoSuchThing,
498 | errno == eNOENT = (NoSuchThing,
499 "no such file or directory")
500 | errno == eNOEXEC = (InvalidArgument,
501 "not an executable file")
502 | errno == eNOLCK = (ResourceExhausted,
503 "no file locks available")
504 | errno == eNOLINK = (ResourceVanished,
505 "RFS link has been severed")
506 | errno == eNOMEM = (ResourceExhausted,
507 "not enough virtual memory")
508 | errno == eNOMSG = (NoSuchThing,
509 "no message of desired type")
510 | errno == eNONET = (NoSuchThing,
511 "host is not on a network")
512 | errno == eNOPROTOOPT = (UnsupportedOperation,
513 "operation not supported by protocol")
514 | errno == eNOSPC = (ResourceExhausted,
515 "no space left on device")
516 | errno == eNOSR = (ResourceExhausted,
517 "out of stream resources")
518 | errno == eNOSTR = (InvalidArgument,
519 "not a stream device")
520 | errno == eNOSYS = (UnsupportedOperation,
521 "function not implemented")
522 | errno == eNOTBLK = (InvalidArgument,
523 "not a block device")
524 | errno == eNOTCONN = (InvalidArgument,
525 "socket is not connected")
526 | errno == eNOTDIR = (InappropriateType,
528 | errno == eNOTEMPTY = (UnsatisfiedConstraints,
529 "directory not empty")
530 | errno == eNOTSOCK = (InvalidArgument,
532 | errno == eNOTTY = (IllegalOperation,
533 "inappropriate ioctl for device")
534 | errno == eNXIO = (NoSuchThing,
535 "no such device or address")
536 | errno == eOPNOTSUPP = (UnsupportedOperation,
537 "operation not supported on socket")
538 | errno == ePERM = (PermissionDenied,
539 "privileged operation")
540 | errno == ePFNOSUPPORT = (UnsupportedOperation,
541 "protocol family not supported")
542 | errno == ePIPE = (ResourceVanished,
544 | errno == ePROCLIM = (PermissionDenied,
545 "too many processes")
546 | errno == ePROCUNAVAIL = (UnsupportedOperation,
547 "unimplemented RPC procedure")
548 | errno == ePROGMISMATCH = (ProtocolError,
549 "unsupported RPC program version")
550 | errno == ePROGUNAVAIL = (UnsupportedOperation,
551 "RPC program unavailable")
552 | errno == ePROTO = (ProtocolError,
553 "error in streams protocol")
554 | errno == ePROTONOSUPPORT = (ProtocolError,
555 "protocol not supported")
556 | errno == ePROTOTYPE = (ProtocolError,
557 "wrong protocol for socket")
558 | errno == eRANGE = (UnsupportedOperation,
560 | errno == eREMCHG = (ResourceVanished,
561 "remote address changed")
562 | errno == eREMOTE = (IllegalOperation,
563 "too many levels of remote in path")
564 | errno == eROFS = (PermissionDenied,
565 "read-only file system")
566 | errno == eRPCMISMATCH = (ProtocolError,
567 "RPC version is wrong")
568 | errno == eRREMOTE = (IllegalOperation,
570 | errno == eSHUTDOWN = (IllegalOperation,
571 "can't send after socket shutdown")
572 | errno == eSOCKTNOSUPPORT = (UnsupportedOperation,
573 "socket type not supported")
574 | errno == eSPIPE = (UnsupportedOperation,
575 "can't seek on a pipe")
576 | errno == eSRCH = (NoSuchThing,
578 | errno == eSRMNT = (UnsatisfiedConstraints,
579 "RFS resources still mounted by " ++
581 -- no multiline strings with cpp
582 | errno == eSTALE = (ResourceVanished,
583 "stale NFS file handle")
584 | errno == eTIME = (TimeExpired,
586 | errno == eTIMEDOUT = (TimeExpired,
587 "connection timed out")
588 | errno == eTOOMANYREFS = (ResourceExhausted,
589 "too many references; can't splice")
590 | errno == eTXTBSY = (ResourceBusy,
592 | errno == eUSERS = (ResourceExhausted,
594 | errno == eWOULDBLOCK = (OtherError,
595 "operation would block")
596 | errno == eXDEV = (UnsupportedOperation,
597 "can't make a cross-device link")
598 | otherwise = (OtherError,
599 "unexpected error (error code: "