2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[PrelHandle]{Module @PrelHandle@}
7 This module defines Haskell {\em handles} and the basic operations
8 which are supported for them.
11 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
15 module PrelHandle where
18 import PrelArr ( newVar, readVar, writeVar, ByteArray )
19 import PrelRead ( Read )
20 import PrelList ( span )
22 import PrelMaybe ( Maybe(..) )
23 import PrelAddr ( Addr, nullAddr )
24 import PrelBounded () -- get at Bounded Int instance.
25 import PrelNum ( toInteger )
28 #ifndef __PARALLEL_HASKELL__
29 import PrelForeign ( ForeignObj, makeForeignObj, writeForeignObj )
32 import PrelConc -- concurrent only
36 %*********************************************************
38 \subsection{Types @Handle@, @Handle__@}
40 %*********************************************************
42 The @Handle@ and @Handle__@ types are defined in @IOBase@.
45 {-# INLINE newHandle #-}
46 {-# INLINE readHandle #-}
47 {-# INLINE writeHandle #-}
48 newHandle :: Handle__ -> IO Handle
49 readHandle :: Handle -> IO Handle__
50 writeHandle :: Handle -> Handle__ -> IO ()
52 #if defined(__CONCURRENT_HASKELL__)
54 -- Use MVars for concurrent Haskell
55 newHandle hc = newMVar hc >>= \ h ->
58 readHandle (Handle h) = takeMVar h
59 writeHandle (Handle h) hc = putMVar h hc
63 -- Use ordinary MutableVars for non-concurrent Haskell
64 newHandle hc = stToIO (newVar hc >>= \ h ->
67 readHandle (Handle h) = stToIO (readVar h)
68 writeHandle (Handle h) hc = stToIO (writeVar h hc)
74 %*********************************************************
76 \subsection[StdHandles]{Standard handles}
78 %*********************************************************
80 Three handles are allocated during program initialisation. The first
81 two manage input or output from the Haskell program's standard input
82 or output channel respectively. The third manages output to the
83 standard error channel. These handles are initially open.
86 stdin, stdout, stderr :: Handle
88 stdout = unsafePerformIO (do
89 rc <- _ccall_ getLock 1 1 -- ConcHask: SAFE, won't block
91 0 -> newHandle (mkClosedHandle__)
93 #ifndef __CONCURRENT_HASKELL__
94 fo <- _ccall_ openStdFile 1 1{-flush on close-} 0{-writeable-} -- ConcHask: SAFE, won't block
96 fo <- _ccall_ openStdFile 1 (1{-flush on close-} + 128{-don't block on I/O-})
97 0{-writeable-} -- ConcHask: SAFE, won't block
100 #ifndef __PARALLEL_HASKELL__
101 fo <- makeForeignObj fo (``&freeStdFileObject''::Addr)
103 (bm, bf_size) <- getBMode__ fo
104 mkBuffer__ fo bf_size
105 newHandle (Handle__ fo WriteHandle bm "stdout")
106 _ -> do ioError <- constructError "stdout"
107 newHandle (mkErrorHandle__ ioError)
110 stdin = unsafePerformIO (do
111 rc <- _ccall_ getLock 0 0 -- ConcHask: SAFE, won't block
113 0 -> newHandle (mkClosedHandle__)
115 #ifndef __CONCURRENT_HASKELL__
116 fo <- _ccall_ openStdFile 0 0{-don't flush on close -} 1{-readable-} -- ConcHask: SAFE, won't block
118 fo <- _ccall_ openStdFile 0 (0{-flush on close-} + 128{-don't block on I/O-})
119 1{-readable-} -- ConcHask: SAFE, won't block
122 #ifndef __PARALLEL_HASKELL__
123 fo <- makeForeignObj fo (``&freeStdFileObject''::Addr)
125 (bm, bf_size) <- getBMode__ fo
126 mkBuffer__ fo bf_size
127 hdl <- newHandle (Handle__ fo ReadHandle bm "stdin")
128 -- when stdin and stdout are both connected to a terminal, ensure
129 -- that anything buffered on stdout is flushed prior to reading from stdin.
131 hConnectTerms stdout hdl
133 _ -> do ioError <- constructError "stdin"
134 newHandle (mkErrorHandle__ ioError)
138 stderr = unsafePerformIO (do
139 rc <- _ccall_ getLock 2 1 -- ConcHask: SAFE, won't block
141 0 -> newHandle (mkClosedHandle__)
143 #ifndef __CONCURRENT_HASKELL__
144 fo <- _ccall_ openStdFile 2 1{-flush on close-} 0{-writeable-} -- ConcHask: SAFE, won't block
146 fo <- _ccall_ openStdFile 2 (1{-flush on close-} + 128{-don't block on I/O-})
147 0{-writeable-} -- ConcHask: SAFE, won't block
150 #ifndef __PARALLEL_HASKELL__
151 fo <- makeForeignObj fo (``&freeStdFileObject''::Addr)
153 hdl <- newHandle (Handle__ fo WriteHandle NoBuffering "stderr")
154 -- when stderr and stdout are both connected to a terminal, ensure
155 -- that anything buffered on stdout is flushed prior to writing on stderr.
157 hConnectTo stdout hdl
159 _ -> do ioError <- constructError "stderr"
160 newHandle (mkErrorHandle__ ioError)
164 %*********************************************************
166 \subsection[OpeningClosing]{Opening and Closing Files}
168 %*********************************************************
171 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
172 deriving (Eq, Ord, Ix, Enum, Read, Show)
177 deriving (Eq, Read, Show)
179 openFile :: FilePath -> IOMode -> IO Handle
180 openFile fp im = openFileEx fp (TextMode im)
182 openFileEx :: FilePath -> IOModeEx -> IO Handle
185 fo <- _ccall_ openFile f file_mode binary flush_on_close -- ConcHask: SAFE, won't block
186 if fo /= nullAddr then do
187 #ifndef __PARALLEL_HASKELL__
188 fo <- makeForeignObj fo ((``&freeFileObject'')::Addr)
190 (bm, bf_size) <- getBMode__ fo
191 mkBuffer__ fo bf_size
192 newHandle (Handle__ fo htype bm f)
194 constructErrorAndFailWithInfo "openFile" f
198 BinaryMode imo -> (imo, 1)
199 TextMode imo -> (imo, 0)
201 #ifndef __CONCURRENT_HASKELL__
202 file_mode = file_mode'
204 file_mode = file_mode' + 128{-Don't block on I/O-}
207 (flush_on_close, file_mode') =
212 ReadWriteMode -> (1, 3)
215 ReadMode -> ReadHandle
216 WriteMode -> WriteHandle
217 AppendMode -> AppendHandle
218 ReadWriteMode -> ReadWriteHandle
221 Computation $openFile file mode$ allocates and returns a new, open
222 handle to manage the file {\em file}. It manages input if {\em mode}
223 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
224 and both input and output if mode is $ReadWriteMode$.
226 If the file does not exist and it is opened for output, it should be
227 created as a new file. If {\em mode} is $WriteMode$ and the file
228 already exists, then it should be truncated to zero length. The
229 handle is positioned at the end of the file if {\em mode} is
230 $AppendMode$, and otherwise at the beginning (in which case its
231 internal position is 0).
233 Implementations should enforce, locally to the Haskell process,
234 multiple-reader single-writer locking on files, which is to say that
235 there may either be many handles on the same file which manage input,
236 or just one handle on the file which manages output. If any open or
237 semi-closed handle is managing a file for output, no new handle can be
238 allocated for that file. If any open or semi-closed handle is
239 managing a file for input, new handles can only be allocated if they
240 do not manage output.
242 Two files are the same if they have the same absolute name. An
243 implementation is free to impose stricter conditions.
246 hClose :: Handle -> IO ()
249 handle_ <- readHandle handle
250 case haType__ handle_ of
251 ErrorHandle ioError -> do
252 writeHandle handle handle_
255 writeHandle handle handle_
256 ioe_closedHandle "hClose" handle
258 rc <- _ccall_ closeFile (haFO__ handle_) 1{-flush if you can-} -- ConcHask: SAFE, won't block
259 {- We explicitly close a file object so that we can be told
260 if there were any errors. Note that after @hClose@
261 has been performed, the ForeignObj embedded in the Handle
262 is still lying around in the heap, so care is taken
263 to avoid closing the file object when the ForeignObj
264 is finalised. (we overwrite the file ptr in the underlying
265 FileObject with a NULL as part of closeFile())
269 writeHandle handle (handle_{ haType__ = ClosedHandle,
270 haFO__ = nullFile__ })
272 writeHandle handle handle_
273 constructErrorAndFail "hClose"
277 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
278 computation finishes, any items buffered for output and not already
279 sent to the operating system are flushed as for $flush$.
281 %*********************************************************
283 \subsection[EOF]{Detecting the End of Input}
285 %*********************************************************
288 For a handle {\em hdl} which attached to a physical file, $hFileSize
289 hdl$ returns the size of {\em hdl} in terms of the number of items
290 which can be read from {\em hdl}.
293 hFileSize :: Handle -> IO Integer
294 hFileSize handle = do
295 handle_ <- readHandle handle
296 case haType__ handle_ of
297 ErrorHandle ioError -> do
298 writeHandle handle handle_
301 writeHandle handle handle_
302 ioe_closedHandle "hFileSize" handle
303 SemiClosedHandle -> do
304 writeHandle handle handle_
305 ioe_closedHandle "hFileSize" handle
307 -- HACK! We build a unique MP_INT of the right shape to hold
308 -- a single unsigned word, and we let the C routine
309 -- change the data bits
311 -- For some reason, this fails to typecheck if converted to a do
313 _casm_ ``%r = 1;'' >>= \(I# hack#) ->
314 case int2Integer# hack# of
315 result@(J# _ _ d#) -> do
316 rc <- _ccall_ fileSize (haFO__ handle_) d# -- ConcHask: SAFE, won't block
317 writeHandle handle handle_
321 constructErrorAndFail "hFileSize"
324 For a readable handle {\em hdl}, @hIsEOF hdl@ returns
325 @True@ if no further input can be taken from @hdl@ or for a
326 physical file, if the current I/O position is equal to the length of
327 the file. Otherwise, it returns @False@.
330 hIsEOF :: Handle -> IO Bool
332 handle_ <- wantReadableHandle "hIsEOF" handle
333 let fo = haFO__ handle_
334 rc <- mayBlock fo (_ccall_ fileEOF fo) -- ConcHask: UNSAFE, may block
335 writeHandle handle handle_
339 _ -> constructErrorAndFail "hIsEOF"
345 %*********************************************************
347 \subsection[Buffering]{Buffering Operations}
349 %*********************************************************
351 Three kinds of buffering are supported: line-buffering,
352 block-buffering or no-buffering. See @IOBase@ for definition
353 and further explanation of what the type represent.
355 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
356 handle {\em hdl} on subsequent reads and writes.
360 If {\em mode} is @LineBuffering@, line-buffering should be
363 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
364 should be enabled if possible. The size of the buffer is {\em n} items
365 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
367 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
370 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
371 to @NoBuffering@, then any items in the output buffer are written to
372 the device, and any items in the input buffer are discarded. The
373 default buffering mode when a handle is opened is
374 implementation-dependent and may depend on the object which is
375 attached to that handle.
378 hSetBuffering :: Handle -> BufferMode -> IO ()
380 hSetBuffering handle mode =
382 BlockBuffering (Just n)
383 | n <= 0 -> fail (IOError (Just handle)
386 ("illegal buffer size " ++ showsPrec 9 n [])) -- 9 => should be parens'ified.
388 handle_ <- readHandle handle
389 case haType__ handle_ of
390 ErrorHandle ioError -> do
391 writeHandle handle handle_
394 writeHandle handle handle_
395 ioe_closedHandle "hSetBuffering" handle
398 - we flush the old buffer regardless of whether
399 the new buffer could fit the contents of the old buffer
401 - allow a handle's buffering to change even if IO has
402 occurred (ANSI C spec. does not allow this, nor did
403 the previous implementation of IO.hSetBuffering).
404 - a non-standard extension is to allow the buffering
405 of semi-closed handles to change [sof 6/98]
407 let fo = haFO__ handle_
408 rc <- mayBlock fo (_ccall_ setBuffering fo bsize) -- ConcHask: UNSAFE, may block
411 writeHandle handle (handle_{ haBufferMode__ = mode })
413 -- Note: failure to change the buffer size will cause old buffer to be flushed.
414 writeHandle handle handle_
415 constructErrorAndFail "hSetBuffering"
421 BlockBuffering Nothing -> -2
422 BlockBuffering (Just n) -> n
425 The action @hFlush hdl@ causes any items buffered for output
426 in handle {\em hdl} to be sent immediately to the operating
430 hFlush :: Handle -> IO ()
432 handle_ <- wantWriteableHandle "hFlush" handle
433 let fo = haFO__ handle_
434 rc <- mayBlock fo (_ccall_ flushFile fo) -- ConcHask: UNSAFE, may block
435 writeHandle handle handle_
439 constructErrorAndFail "hFlush"
444 %*********************************************************
446 \subsection[Seeking]{Repositioning Handles}
448 %*********************************************************
453 Handle -- Q: should this be a weak or strong ref. to the handle?
456 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
457 deriving (Eq, Ord, Ix, Enum, Read, Show)
460 Computation @hGetPosn hdl@ returns the current I/O
461 position of {\em hdl} as an abstract position. Computation
462 $hSetPosn p$ sets the position of {\em hdl}
463 to a previously obtained position {\em p}.
466 hGetPosn :: Handle -> IO HandlePosn
468 handle_ <- wantSeekableHandle "hGetPosn" handle
469 posn <- _ccall_ getFilePosn (haFO__ handle_) -- ConcHask: SAFE, won't block
470 writeHandle handle handle_
472 return (HandlePosn handle posn)
474 constructErrorAndFail "hGetPosn"
476 hSetPosn :: HandlePosn -> IO ()
477 hSetPosn (HandlePosn handle posn) = do
478 handle_ <- wantSeekableHandle "hSetPosn" handle -- not as silly as it looks: the handle may have been closed in the meantime.
479 let fo = haFO__ handle_
480 rc <- mayBlock fo (_ccall_ setFilePosn fo posn) -- ConcHask: UNSAFE, may block
481 writeHandle handle handle_
485 constructErrorAndFail "hSetPosn"
488 The action @hSeek hdl mode i@ sets the position of handle
489 @hdl@ depending on @mode@. If @mode@ is
491 \item[{\bf AbsoluteSeek}] The position of @hdl@ is set to @i@.
492 \item[{\bf RelativeSeek}] The position of @hdl@ is set to offset @i@ from
493 the current position.
494 \item[{\bf SeekFromEnd}] The position of @hdl@ is set to offset @i@ from
498 Some handles may not be seekable (see @hIsSeekable@), or only support a
499 subset of the possible positioning operations (e.g. it may only be
500 possible to seek to the end of a tape, or to a positive offset from
501 the beginning or current position).
503 It is not possible to set a negative I/O position, or for a physical
504 file, an I/O position beyond the current end-of-file.
507 - when seeking using @SeekFromEnd@, positive offsets (>=0) means seeking
509 - relative seeking on buffered handles can lead to non-obvious results.
512 hSeek :: Handle -> SeekMode -> Integer -> IO ()
513 hSeek handle mode offset@(J# _ s# d#) = do
514 handle_ <- wantSeekableHandle "hSeek" handle
515 let fo = haFO__ handle_
516 rc <- mayBlock fo (_ccall_ seekFile fo whence (I# s#) d#) -- ConcHask: UNSAFE, may block
517 writeHandle handle handle_
521 constructErrorAndFail "hSeek"
524 whence = case mode of
530 %*********************************************************
532 \subsection[Query]{Handle Properties}
534 %*********************************************************
536 A number of operations return information about the properties of a
537 handle. Each of these operations returns $True$ if the
538 handle has the specified property, and $False$
541 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
542 {\em hdl} is not block-buffered. Otherwise it returns
543 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
544 $( Just n )$ for block-buffering of {\em n} bytes.
547 hIsOpen :: Handle -> IO Bool
549 handle_ <- readHandle handle
550 case haType__ handle_ of
551 ErrorHandle ioError -> do
552 writeHandle handle handle_
555 writeHandle handle handle_
557 SemiClosedHandle -> do
558 writeHandle handle handle_
561 writeHandle handle handle_
564 hIsClosed :: Handle -> IO Bool
565 hIsClosed handle = do
566 handle_ <- readHandle handle
567 case haType__ handle_ of
568 ErrorHandle ioError -> do
569 writeHandle handle handle_
572 writeHandle handle handle_
575 writeHandle handle handle_
578 {- not defined, nor exported, but mentioned
579 here for documentation purposes:
581 hSemiClosed :: Handle -> IO Bool
585 return (not (ho || hc))
588 hIsReadable :: Handle -> IO Bool
589 hIsReadable handle = do
590 handle_ <- readHandle handle
591 case haType__ handle_ of
592 ErrorHandle ioError -> do
593 writeHandle handle handle_
596 writeHandle handle handle_
597 ioe_closedHandle "hIsReadable" handle
598 SemiClosedHandle -> do
599 writeHandle handle handle_
600 ioe_closedHandle "hIsReadable" handle
602 writeHandle handle handle_
603 return (isReadable htype)
605 isReadable ReadHandle = True
606 isReadable ReadWriteHandle = True
609 hIsWritable :: Handle -> IO Bool
610 hIsWritable handle = do
611 handle_ <- readHandle handle
612 case haType__ handle_ of
613 ErrorHandle ioError -> do
614 writeHandle handle handle_
617 writeHandle handle handle_
618 ioe_closedHandle "hIsWritable" handle
619 SemiClosedHandle -> do
620 writeHandle handle handle_
621 ioe_closedHandle "hIsWritable" handle
623 writeHandle handle handle_
624 return (isWritable htype)
626 isWritable AppendHandle = True
627 isWritable WriteHandle = True
628 isWritable ReadWriteHandle = True
632 #ifndef __PARALLEL_HASKELL__
633 getBMode__ :: ForeignObj -> IO (BufferMode, Int)
635 getBMode__ :: Addr -> IO (BufferMode, Int)
638 rc <- _ccall_ getBufferMode fo -- ConcHask: SAFE, won't block
640 0 -> return (NoBuffering, 0)
641 -1 -> return (LineBuffering, default_buffer_size)
642 -2 -> return (BlockBuffering Nothing, default_buffer_size)
643 -3 -> return (NoBuffering, 0) -- only happens on un-stat()able files.
644 n -> return (BlockBuffering (Just n), n)
646 default_buffer_size :: Int
647 default_buffer_size = (``BUFSIZ'' - 1)
650 Querying how a handle buffers its data:
653 hGetBuffering :: Handle -> IO BufferMode
654 hGetBuffering handle = do
655 handle_ <- readHandle handle
656 case haType__ handle_ of
657 ErrorHandle ioError -> do
658 writeHandle handle handle_
661 writeHandle handle handle_
662 ioe_closedHandle "hGetBuffering" handle
665 We're being non-standard here, and allow the buffering
666 of a semi-closed handle to be queried. -- sof 6/98
668 let v = haBufferMode__ handle_
669 writeHandle handle handle_
670 return v -- could be stricter..
675 hIsSeekable :: Handle -> IO Bool
676 hIsSeekable handle = do
677 handle_ <- readHandle handle
678 case haType__ handle_ of
679 ErrorHandle ioError -> do
680 writeHandle handle handle_
683 writeHandle handle handle_
684 ioe_closedHandle "hIsSeekable" handle
685 SemiClosedHandle -> do
686 writeHandle handle handle_
687 ioe_closedHandle "hIsSeekable" handle
689 writeHandle handle handle_
692 rc <- _ccall_ seekFileP (haFO__ handle_) -- ConcHask: SAFE, won't block
693 writeHandle handle handle_
697 _ -> constructErrorAndFail "hIsSeekable"
701 %*********************************************************
703 \subsection{Changing echo status}
705 %*********************************************************
707 Non-standard GHC extension is to allow the echoing status
708 of a handles connected to terminals to be reconfigured:
711 hSetEcho :: Handle -> Bool -> IO ()
713 isT <- hIsTerminalDevice hdl
717 handle_ <- readHandle hdl
718 case haType__ handle_ of
719 ErrorHandle ioError -> do
720 writeHandle hdl handle_
723 writeHandle hdl handle_
724 ioe_closedHandle "hSetEcho" hdl
726 rc <- _ccall_ setTerminalEcho (haFO__ handle_) (if on then 1 else 0) -- ConcHask: SAFE, won't block
727 writeHandle hdl handle_
730 else constructErrorAndFail "hSetEcho"
732 hGetEcho :: Handle -> IO Bool
734 isT <- hIsTerminalDevice hdl
738 handle_ <- readHandle hdl
739 case haType__ handle_ of
740 ErrorHandle ioError -> do
741 writeHandle hdl handle_
744 writeHandle hdl handle_
745 ioe_closedHandle "hGetEcho" hdl
747 rc <- _ccall_ getTerminalEcho (haFO__ handle_) -- ConcHask: SAFE, won't block
748 writeHandle hdl handle_
752 _ -> constructErrorAndFail "hSetEcho"
754 hIsTerminalDevice :: Handle -> IO Bool
755 hIsTerminalDevice hdl = do
756 handle_ <- readHandle hdl
757 case haType__ handle_ of
758 ErrorHandle ioError -> do
759 writeHandle hdl handle_
762 writeHandle hdl handle_
763 ioe_closedHandle "hIsTerminalDevice" hdl
765 rc <- _ccall_ isTerminalDevice (haFO__ handle_) -- ConcHask: SAFE, won't block
766 writeHandle hdl handle_
770 _ -> constructErrorAndFail "hIsTerminalDevice"
774 hConnectTerms :: Handle -> Handle -> IO ()
775 hConnectTerms hW hR = hConnectHdl_ hW hR 1{-check if they're both coming connected to ttys-}
777 hConnectTo :: Handle -> Handle -> IO ()
778 hConnectTo hW hR = hConnectHdl_ hW hR 0{-connect regardless-}
780 hConnectHdl_ :: Handle -> Handle -> Int -> IO ()
781 hConnectHdl_ hW hR is_tty = do
782 hW_ <- wantRWHandle "hConnectTo" hW
783 hR_ <- wantRWHandle "hConnectTo" hR
784 _ccall_ setConnectedTo (haFO__ hR_) (haFO__ hW_) is_tty -- ConcHask: SAFE, won't block
788 #ifndef __PARALLEL_HASKELL__
789 #define FILE_OBJECT ForeignObj
791 #define FILE_OBJECT Addr
794 flushConnectedHandle :: FILE_OBJECT -> IO ()
795 flushConnectedHandle fo = _ccall_ flushConnectedHandle fo
798 As an extension, we also allow characters to be pushed back.
799 Like ANSI C stdio, we guarantee no more than one character of
800 pushback. (For unbuffered channels, the (default) push-back limit is
804 hUngetChar :: Handle -> Char -> IO ()
805 hUngetChar handle c = do
806 handle_ <- wantReadableHandle "hLookAhead" handle
807 rc <- _ccall_ ungetChar (haFO__ handle_) c -- ConcHask: SAFE, won't block
808 writeHandle handle handle_
810 then constructErrorAndFail "hUngetChar"
816 Hoisting files in in one go is sometimes useful, so we support
817 this as an extension:
820 -- in one go, read file into an externally allocated buffer.
821 slurpFile :: FilePath -> IO (Addr, Int)
823 hdl <- openFile fname ReadMode
825 if sz > toInteger (maxBound::Int) then
826 fail (userError "slurpFile: file too big")
828 let sz_i = fromInteger sz
829 chunk <- _ccall_ allocMemory__ (sz_i::Int)
833 constructErrorAndFail "slurpFile"
835 handle_ <- readHandle hdl
836 let fo = haFO__ handle_
837 rc <- mayBlock fo (_ccall_ readChunk fo chunk sz_i) -- ConcHask: UNSAFE, may block.
838 writeHandle hdl handle_
841 then constructErrorAndFail "slurpFile"
842 else return (chunk, rc)
844 hFillBufBA :: Handle -> ByteArray Int -> Int -> IO Int
845 hFillBufBA handle buf sz
846 | sz <= 0 = fail (IOError (Just handle)
849 ("illegal buffer size " ++ showsPrec 9 sz [])) -- 9 => should be parens'ified.
851 handle_ <- wantReadableHandle "hFillBufBA" handle
852 let fo = haFO__ handle_
853 rc <- mayBlock fo (_ccall_ readChunk fo buf sz) -- ConcHask: UNSAFE, may block.
854 writeHandle handle handle_
857 else constructErrorAndFail "hFillBufBA"
859 hFillBuf :: Handle -> Addr -> Int -> IO Int
860 hFillBuf handle buf sz
861 | sz <= 0 = fail (IOError (Just handle)
864 ("illegal buffer size " ++ showsPrec 9 sz [])) -- 9 => should be parens'ified.
866 handle_ <- wantReadableHandle "hFillBuf" handle
867 let fo = haFO__ handle_
868 rc <- mayBlock fo (_ccall_ readChunk fo buf sz) -- ConcHask: UNSAFE, may block.
869 writeHandle handle handle_
872 else constructErrorAndFail "hFillBuf"
876 The @hPutBuf hdl buf len@ action writes an already packed sequence of
877 bytes to the file/channel managed by @hdl@ - non-standard.
880 hPutBuf :: Handle -> Addr -> Int -> IO ()
881 hPutBuf handle buf len = do
882 handle_ <- wantWriteableHandle "hPutBuf" handle
883 let fo = haFO__ handle_
884 rc <- mayBlock fo (_ccall_ writeBuf fo buf len) -- ConcHask: UNSAFE, may block.
885 writeHandle handle handle_
888 else constructErrorAndFail "hPutBuf"
890 hPutBufBA :: Handle -> ByteArray Int -> Int -> IO ()
891 hPutBufBA handle buf len = do
892 handle_ <- wantWriteableHandle "hPutBufBA" handle
893 let fo = haFO__ handle_
894 rc <- mayBlock fo (_ccall_ writeBufBA fo buf len) -- ConcHask: UNSAFE, may block.
895 writeHandle handle handle_
898 else constructErrorAndFail "hPutBuf"
901 Sometimes it's useful to get at the file descriptor that
902 the Handle contains..
905 getHandleFd :: Handle -> IO Int
906 getHandleFd handle = do
907 handle_ <- readHandle handle
908 case (haType__ handle_) of
909 ErrorHandle ioError -> do
910 writeHandle handle handle_
913 writeHandle handle handle_
914 ioe_closedHandle "getHandleFd" handle
916 fd <- _ccall_ getFileFd (haFO__ handle_)
917 writeHandle handle handle_
922 %*********************************************************
924 \subsection{Miscellaneous}
926 %*********************************************************
928 These three functions are meant to get things out of @IOErrors@.
933 ioeGetFileName :: IOError -> Maybe FilePath
934 ioeGetErrorString :: IOError -> String
935 ioeGetHandle :: IOError -> Maybe Handle
937 ioeGetHandle (IOError h _ _ _) = h
938 ioeGetErrorString (IOError _ iot _ str) =
943 ioeGetFileName (IOError _ _ _ str) =
944 case span (/=':') str of
950 A number of operations want to get at a readable or writeable handle, and fail
954 wantReadableHandle :: String -> Handle -> IO Handle__
955 wantReadableHandle fun handle = do
956 handle_ <- readHandle handle
957 case haType__ handle_ of
958 ErrorHandle ioError -> do
959 writeHandle handle handle_
962 writeHandle handle handle_
963 ioe_closedHandle fun handle
964 SemiClosedHandle -> do
965 writeHandle handle handle_
966 ioe_closedHandle fun handle
968 writeHandle handle handle_
969 fail not_readable_error
971 writeHandle handle handle_
972 fail not_readable_error
973 other -> return handle_
976 IOError (Just handle) IllegalOperation fun
977 ("handle is not open for reading")
979 wantWriteableHandle :: String -> Handle -> IO Handle__
980 wantWriteableHandle fun handle = do
981 handle_ <- readHandle handle
982 case haType__ handle_ of
983 ErrorHandle ioError -> do
984 writeHandle handle handle_
987 writeHandle handle handle_
988 ioe_closedHandle fun handle
989 SemiClosedHandle -> do
990 writeHandle handle handle_
991 ioe_closedHandle fun handle
993 writeHandle handle handle_
994 fail not_writeable_error
995 other -> return handle_
997 not_writeable_error =
998 IOError (Just handle) IllegalOperation fun
999 ("handle is not open for writing")
1002 wantRWHandle :: String -> Handle -> IO Handle__
1003 wantRWHandle fun handle = do
1004 handle_ <- readHandle handle
1005 case haType__ handle_ of
1006 ErrorHandle ioError -> do
1007 writeHandle handle handle_
1010 writeHandle handle handle_
1011 ioe_closedHandle fun handle
1012 SemiClosedHandle -> do
1013 writeHandle handle handle_
1014 ioe_closedHandle fun handle
1015 other -> return handle_
1017 not_readable_error =
1018 IOError (Just handle) IllegalOperation fun
1019 ("handle is not open for reading or writing")
1021 wantSeekableHandle :: String -> Handle -> IO Handle__
1022 wantSeekableHandle fun handle = do
1023 handle_ <- readHandle handle
1024 case haType__ handle_ of
1025 ErrorHandle ioError -> do
1026 writeHandle handle handle_
1029 writeHandle handle handle_
1030 ioe_closedHandle fun handle
1031 SemiClosedHandle -> do
1032 writeHandle handle handle_
1033 ioe_closedHandle fun handle
1035 writeHandle handle handle_
1036 fail not_seekable_error
1039 not_seekable_error =
1040 IOError (Just handle)
1041 IllegalOperation fun
1042 ("handle is not seekable")
1046 Internal function for creating an @IOError@ representing the
1047 access to a closed file.
1050 ioe_closedHandle :: String -> Handle -> IO a
1051 ioe_closedHandle fun h = fail (IOError (Just h) IllegalOperation fun "handle is closed")
1054 Internal helper functions for Concurrent Haskell implementation
1058 #ifndef __PARALLEL_HASKELL__
1059 mayBlock :: ForeignObj -> IO Int -> IO Int
1061 mayBlock :: Addr -> IO Int -> IO Int
1064 #ifndef __CONCURRENT_HASKELL__
1065 mayBlock _ act = act
1067 mayBlock fo act = do
1070 -5 -> do -- (possibly blocking) read
1071 fd <- _ccall_ getFileFd fo
1073 _ccall_ clearNonBlockingIOFlag__ fo -- force read to happen this time.
1074 mayBlock fo act -- input available, re-try
1075 -6 -> do -- (possibly blocking) write
1076 fd <- _ccall_ getFileFd fo
1078 _ccall_ clearNonBlockingIOFlag__ fo -- force write to happen this time.
1079 mayBlock fo act -- output possible
1080 -7 -> do -- (possibly blocking) write on connected handle
1081 fd <- _ccall_ getConnFileFd fo
1083 _ccall_ clearConnNonBlockingIOFlag__ fo -- force write to happen this time.
1084 mayBlock fo act -- output possible
1086 _ccall_ setNonBlockingIOFlag__ fo -- reset file object.
1087 _ccall_ setConnNonBlockingIOFlag__ fo -- reset (connected) file object.