-wantReadableHandle :: Handle -> IO Handle__
-wantReadableHandle handle = do
- htype <- readHandle handle
- case htype of
- ErrorHandle ioError -> do
- writeHandle handle htype
- fail ioError
- ClosedHandle -> do
- writeHandle handle htype
- ioe_closedHandle handle
- SemiClosedHandle _ _ -> do
- writeHandle handle htype
- ioe_closedHandle handle
- AppendHandle _ _ _ -> do
- writeHandle handle htype
- fail (IOError (Just handle) IllegalOperation
- "handle is not open for reading")
- WriteHandle _ _ _ -> do
- writeHandle handle htype
- fail (IOError (Just handle) IllegalOperation
- "handle is not open for reading")
- other -> return other
-
-wantWriteableHandle :: Handle
- -> IO Handle__
-wantWriteableHandle handle = do
- htype <- readHandle handle
- case htype of
- ErrorHandle ioError -> do
- writeHandle handle htype
- fail ioError
- ClosedHandle -> do
- writeHandle handle htype
- ioe_closedHandle handle
- SemiClosedHandle _ _ -> do
- writeHandle handle htype
- ioe_closedHandle handle
- ReadHandle _ _ _ -> do
- writeHandle handle htype
- fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
- other -> return other
+wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantReadableHandle fun handle act =
+ withHandle_ handle $ \ handle_ -> do
+ case haType__ handle_ of
+ ErrorHandle theError -> ioError theError
+ ClosedHandle -> ioe_closedHandle fun handle
+ SemiClosedHandle -> ioe_closedHandle fun handle
+ AppendHandle -> ioError not_readable_error
+ WriteHandle -> ioError not_readable_error
+ _ -> act handle_
+ where
+ not_readable_error =
+ IOError (Just handle) IllegalOperation fun
+ ("handle is not open for reading")
+
+wantWriteableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantWriteableHandle fun handle act =
+ withHandle_ handle $ \ handle_ -> do
+ case haType__ handle_ of
+ ErrorHandle theError -> ioError theError
+ ClosedHandle -> ioe_closedHandle fun handle
+ SemiClosedHandle -> ioe_closedHandle fun handle
+ ReadHandle -> ioError not_writeable_error
+ _ -> act handle_
+ where
+ not_writeable_error =
+ IOError (Just handle) IllegalOperation fun
+ ("handle is not open for writing")
+
+wantRWHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantRWHandle fun handle act =
+ withHandle_ handle $ \ handle_ -> do
+ case haType__ handle_ of
+ ErrorHandle theError -> ioError theError
+ ClosedHandle -> ioe_closedHandle fun handle
+ SemiClosedHandle -> ioe_closedHandle fun handle
+ _ -> act handle_
+ where
+ not_rw_error =
+ IOError (Just handle) IllegalOperation fun
+ ("handle is not open for reading or writing")
+
+wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
+wantSeekableHandle fun handle act =
+ withHandle_ handle $ \ handle_ -> do
+ case haType__ handle_ of
+ ErrorHandle theError -> ioError theError
+ ClosedHandle -> ioe_closedHandle fun handle
+ SemiClosedHandle -> ioe_closedHandle fun handle
+ AppendHandle -> ioError not_seekable_error
+ _ -> act handle_
+ where
+ not_seekable_error =
+ IOError (Just handle)
+ IllegalOperation fun
+ ("handle is not seekable")
+
+\end{code}
+
+Internal function for creating an @IOError@ representing the
+access to a closed file.
+
+\begin{code}
+ioe_closedHandle :: String -> Handle -> IO a
+ioe_closedHandle fun h = ioError (IOError (Just h) IllegalOperation fun "handle is closed")
+\end{code}
+
+Internal helper functions for Concurrent Haskell implementation
+of IO:
+
+\begin{code}
+#ifndef __PARALLEL_HASKELL__
+mayBlock :: ForeignObj -> IO Int -> IO Int
+#else
+mayBlock :: Addr -> IO Int -> IO Int
+#endif
+
+#ifndef notyet /*__CONCURRENT_HASKELL__*/
+mayBlock _ act = act
+#else
+mayBlock fo act = do
+ rc <- act
+ case rc of
+ -5 -> do -- (possibly blocking) read
+ fd <- CCALL(getFileFd) fo
+ threadWaitRead fd
+ CCALL(clearNonBlockingIOFlag__) fo -- force read to happen this time.
+ mayBlock fo act -- input available, re-try
+ -6 -> do -- (possibly blocking) write
+ fd <- CCALL(getFileFd) fo
+ threadWaitWrite fd
+ CCALL(clearNonBlockingIOFlag__) fo -- force write to happen this time.
+ mayBlock fo act -- output possible
+ -7 -> do -- (possibly blocking) write on connected handle
+ fd <- CCALL(getConnFileFd) fo
+ threadWaitWrite fd
+ CCALL(clearConnNonBlockingIOFlag__) fo -- force write to happen this time.
+ mayBlock fo act -- output possible
+ _ -> do
+ CCALL(setNonBlockingIOFlag__) fo -- reset file object.
+ CCALL(setConnNonBlockingIOFlag__) fo -- reset (connected) file object.
+ return rc
+
+#endif
+
+-- #ifdef __HUGS__
+#if 1
+threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
+
+-- Hugs does actually have the primops needed to implement these
+-- but, like GHC, the primops don't actually do anything...
+threadDelay _ = return ()
+threadWaitRead _ = return ()
+threadWaitWrite _ = return ()
+#endif
+
+\end{code}
+
+
+\begin{code}
+#ifdef __HUGS__
+type FD = Int
+type Exclusive = Int -- really Bool
+type How = Int
+type Binary = Int
+type OpenStdFlags = Int
+type OpenFlags = Int
+type Readable = Int -- really Bool
+type Flush = Int -- really Bool
+type RC = Int -- standard return code
+
+type IOFileAddr = Addr -- as returned from functions
+type CString = PrimByteArray
+type Bytes = PrimMutableByteArray RealWorld
+
+#ifndef __PARALLEL_HASKELL__
+type FILE_OBJ = ForeignObj -- as passed into functions
+#else
+type FILE_OBJ = Addr
+#endif
+
+foreign import ccall "libHS_cbits.so" "setBuf" unsafe prim_setBuf :: FILE_OBJ -> Addr -> Int -> IO ()
+foreign import ccall "libHS_cbits.so" "getBufSize" unsafe prim_getBufSize :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "inputReady" unsafe prim_inputReady :: FILE_OBJ -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "fileGetc" unsafe prim_fileGetc :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "fileLookAhead" unsafe prim_fileLookAhead :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "readBlock" unsafe prim_readBlock :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "readLine" unsafe prim_readLine :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "readChar" unsafe prim_readChar :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "writeFileObject" unsafe prim_writeFileObject :: FILE_OBJ -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "filePutc" unsafe prim_filePutc :: FILE_OBJ -> Char -> IO RC
+foreign import ccall "libHS_cbits.so" "getBufStart" unsafe prim_getBufStart :: FILE_OBJ -> Int -> IO Addr
+foreign import ccall "libHS_cbits.so" "getWriteableBuf" unsafe prim_getWriteableBuf :: FILE_OBJ -> IO Addr
+foreign import ccall "libHS_cbits.so" "getBufWPtr" unsafe prim_getBufWPtr :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "setBufWPtr" unsafe prim_setBufWPtr :: FILE_OBJ -> Int -> IO ()
+foreign import ccall "libHS_cbits.so" "closeFile" unsafe prim_closeFile :: FILE_OBJ -> Flush -> IO RC
+foreign import ccall "libHS_cbits.so" "fileEOF" unsafe prim_fileEOF :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "setBuffering" unsafe prim_setBuffering :: FILE_OBJ -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "flushFile" unsafe prim_flushFile :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "flushConnectedBuf" unsafe prim_flushConnectedBuf :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "getBufferMode" unsafe prim_getBufferMode :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "seekFile_int64" unsafe prim_seekFile_int64 :: FILE_OBJ -> Int -> Int64 -> IO RC
+foreign import ccall "libHS_cbits.so" "seekFileP" unsafe prim_seekFileP :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "setTerminalEcho" unsafe prim_setTerminalEcho :: FILE_OBJ -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "getTerminalEcho" unsafe prim_getTerminalEcho :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "isTerminalDevice" unsafe prim_isTerminalDevice :: FILE_OBJ -> IO RC
+foreign import ccall "libHS_cbits.so" "setConnectedTo" unsafe prim_setConnectedTo :: FILE_OBJ -> FILE_OBJ -> Int -> IO ()
+foreign import ccall "libHS_cbits.so" "ungetChar" unsafe prim_ungetChar :: FILE_OBJ -> Char -> IO RC
+foreign import ccall "libHS_cbits.so" "readChunk" unsafe prim_readChunk :: FILE_OBJ -> Addr -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "writeBuf" unsafe prim_writeBuf :: FILE_OBJ -> Addr -> Int -> IO RC
+foreign import ccall "libHS_cbits.so" "getFileFd" unsafe prim_getFileFd :: FILE_OBJ -> IO FD
+foreign import ccall "libHS_cbits.so" "fileSize_int64" unsafe prim_fileSize_int64 :: FILE_OBJ -> Bytes -> IO RC
+foreign import ccall "libHS_cbits.so" "getFilePosn" unsafe prim_getFilePosn :: FILE_OBJ -> IO Int
+foreign import ccall "libHS_cbits.so" "setFilePosn" unsafe prim_setFilePosn :: FILE_OBJ -> Int -> IO Int
+foreign import ccall "libHS_cbits.so" "getConnFileFd" unsafe prim_getConnFileFd :: FILE_OBJ -> IO FD
+foreign import ccall "libHS_cbits.so" "allocMemory__" unsafe prim_allocMemory__ :: Int -> IO Addr
+foreign import ccall "libHS_cbits.so" "getLock" unsafe prim_getLock :: FD -> Exclusive -> IO RC
+foreign import ccall "libHS_cbits.so" "openStdFile" unsafe prim_openStdFile :: FD -> OpenStdFlags -> Readable -> IO IOFileAddr
+foreign import ccall "libHS_cbits.so" "openFile" unsafe prim_openFile :: CString -> How -> Binary -> OpenFlags -> IO IOFileAddr
+foreign import ccall "libHS_cbits.so" "freeFileObject" unsafe prim_freeFileObject :: FILE_OBJ -> IO ()
+foreign import ccall "libHS_cbits.so" "freeStdFileObject" unsafe prim_freeStdFileObject :: FILE_OBJ -> IO ()
+foreign import ccall "libHS_cbits.so" "const_BUFSIZ" unsafe const_BUFSIZ :: Int
+
+foreign import ccall "libHS_cbits.so" "setConnNonBlockingIOFlag__" unsafe prim_setConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
+foreign import ccall "libHS_cbits.so" "clearConnNonBlockingIOFlag__" unsafe prim_clearConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
+foreign import ccall "libHS_cbits.so" "setNonBlockingIOFlag__" unsafe prim_setNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
+foreign import ccall "libHS_cbits.so" "clearNonBlockingIOFlag__" unsafe prim_clearNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
+
+foreign import ccall "libHS_cbits.so" "getErrStr__" unsafe prim_getErrStr__ :: IO Addr
+foreign import ccall "libHS_cbits.so" "getErrNo__" unsafe prim_getErrNo__ :: IO Int
+foreign import ccall "libHS_cbits.so" "getErrType__" unsafe prim_getErrType__ :: IO Int