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 ( ByteArray(..), newVar, readVar, writeVar )
19 import PrelRead ( Read )
20 import PrelList ( span )
26 import PrelErr ( error )
30 #ifndef __PARALLEL_HASKELL__
31 import PrelForeign ( ForeignObj, makeForeignObj, writeForeignObj )
34 import PrelConc -- concurrent only
38 %*********************************************************
40 \subsection{Types @FilePath@, @Handle@, @Handle__@}
42 %*********************************************************
44 The @Handle@ and @Handle__@ types are defined in @IOBase@.
47 type FilePath = String
49 {-# INLINE newHandle #-}
50 {-# INLINE readHandle #-}
51 {-# INLINE writeHandle #-}
52 newHandle :: Handle__ -> IO Handle
53 readHandle :: Handle -> IO Handle__
54 writeHandle :: Handle -> Handle__ -> IO ()
56 #if defined(__CONCURRENT_HASKELL__)
58 -- Use MVars for concurrent Haskell
59 newHandle hc = newMVar hc >>= \ h ->
62 readHandle (Handle h) = takeMVar h
63 writeHandle (Handle h) hc = putMVar h hc
67 -- Use ordinary MutableVars for non-concurrent Haskell
68 newHandle hc = stToIO (newVar hc >>= \ h ->
71 readHandle (Handle h) = stToIO (readVar h)
72 writeHandle (Handle h) hc = stToIO (writeVar h hc)
77 %*********************************************************
79 \subsection{Functions}
81 %*********************************************************
84 #ifndef __PARALLEL_HASKELL__
85 filePtr :: Handle__ -> ForeignObj
87 filePtr :: Handle__ -> Addr
89 filePtr (SemiClosedHandle fp _) = fp
90 filePtr (ReadHandle fp _ _) = fp
91 filePtr (WriteHandle fp _ _) = fp
92 filePtr (AppendHandle fp _ _) = fp
93 filePtr (ReadWriteHandle fp _ _) = fp
95 bufferMode :: Handle__ -> Maybe BufferMode
96 bufferMode (ReadHandle _ m _) = m
97 bufferMode (WriteHandle _ m _) = m
98 bufferMode (AppendHandle _ m _) = m
99 bufferMode (ReadWriteHandle _ m _) = m
101 markHandle :: Handle__ -> Handle__
102 markHandle h@(ReadHandle fp m b)
104 | otherwise = ReadHandle fp m True
105 markHandle h@(WriteHandle fp m b)
107 | otherwise = WriteHandle fp m True
108 markHandle h@(AppendHandle fp m b)
110 | otherwise = AppendHandle fp m True
111 markHandle h@(ReadWriteHandle fp m b)
113 | otherwise = ReadWriteHandle fp m True
116 -------------------------------------------
118 %*********************************************************
120 \subsection[StdHandles]{Standard handles}
122 %*********************************************************
124 Three handles are allocated during program initialisation. The first
125 two manage input or output from the Haskell program's standard input
126 or output channel respectively. The third manages output to the
127 standard error channel. These handles are initially open.
130 stdin, stdout, stderr :: Handle
132 stdin = unsafePerformIO (do
133 rc <- _ccall_ getLock (``stdin''::Addr) 0
135 0 -> newHandle ClosedHandle
137 #ifndef __PARALLEL_HASKELL__
138 fp <- makeForeignObj (``stdin''::Addr) (``&freeStdFile''::Addr)
139 newHandle (ReadHandle fp Nothing False)
141 newHandle (ReadHandle ``stdin'' Nothing False)
143 _ -> do ioError <- constructError "stdin"
144 newHandle (ErrorHandle ioError)
147 stdout = unsafePerformIO (do
148 rc <- _ccall_ getLock (``stdout''::Addr) 1
150 0 -> newHandle ClosedHandle
152 #ifndef __PARALLEL_HASKELL__
153 fp <- makeForeignObj (``stdout''::Addr) (``&freeStdFile''::Addr)
154 newHandle (WriteHandle fp Nothing False)
156 newHandle (WriteHandle ``stdout'' Nothing False)
158 _ -> do ioError <- constructError "stdout"
159 newHandle (ErrorHandle ioError)
162 stderr = unsafePerformIO (do
163 rc <- _ccall_ getLock (``stderr''::Addr) 1
165 0 -> newHandle ClosedHandle
167 #ifndef __PARALLEL_HASKELL__
168 fp <- makeForeignObj (``stderr''::Addr) (``&freeStdFile''::Addr)
169 newHandle (WriteHandle fp (Just NoBuffering) False)
171 newHandle (WriteHandle ``stderr'' (Just NoBuffering) False)
173 _ -> do ioError <- constructError "stderr"
174 newHandle (ErrorHandle ioError)
178 %*********************************************************
180 \subsection[OpeningClosing]{Opening and Closing Files}
182 %*********************************************************
185 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
186 deriving (Eq, Ord, Ix, Enum, Read, Show)
191 deriving (Eq, Read, Show)
193 openFile :: FilePath -> IOMode -> IO Handle
194 openFile fp im = openFileEx fp (TextMode im)
196 openFileEx :: FilePath -> IOModeEx -> IO Handle
199 ptr <- _ccall_ openFile f m'
200 if ptr /= ``NULL'' then do
201 #ifndef __PARALLEL_HASKELL__
202 fp <- makeForeignObj ptr ((``&freeFile'')::Addr)
203 newHandle (htype fp Nothing False)
205 newHandle (htype ptr Nothing False)
208 constructErrorAndFailWithInfo "openFile" f
211 BinaryMode imo -> imo
215 BinaryMode _ -> imo' ++ "b"
223 ReadWriteMode -> "r+"
226 ReadMode -> ReadHandle
227 WriteMode -> WriteHandle
228 AppendMode -> AppendHandle
229 ReadWriteMode -> ReadWriteHandle
232 Computation $openFile file mode$ allocates and returns a new, open
233 handle to manage the file {\em file}. It manages input if {\em mode}
234 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
235 and both input and output if mode is $ReadWriteMode$.
237 If the file does not exist and it is opened for output, it should be
238 created as a new file. If {\em mode} is $WriteMode$ and the file
239 already exists, then it should be truncated to zero length. The
240 handle is positioned at the end of the file if {\em mode} is
241 $AppendMode$, and otherwise at the beginning (in which case its
242 internal position is 0).
244 Implementations should enforce, locally to the Haskell process,
245 multiple-reader single-writer locking on files, which is to say that
246 there may either be many handles on the same file which manage input,
247 or just one handle on the file which manages output. If any open or
248 semi-closed handle is managing a file for output, no new handle can be
249 allocated for that file. If any open or semi-closed handle is
250 managing a file for input, new handles can only be allocated if they
251 do not manage output.
253 Two files are the same if they have the same absolute name. An
254 implementation is free to impose stricter conditions.
257 hClose :: Handle -> IO ()
260 htype <- readHandle handle
262 ErrorHandle ioError -> do
263 writeHandle handle htype
266 writeHandle handle htype
267 ioe_closedHandle handle
268 SemiClosedHandle fp (buf,_) -> do
269 (if buf /= ``NULL'' then
273 fp_a <- _casm_ `` %r = (char *)%0; '' fp
274 if fp_a /= (``NULL''::Addr) then do
275 -- Under what condition can this be NULL?
276 rc <- _ccall_ closeFile fp
277 {- We explicitly close a file object so that we can be told
278 if there were any errors. Note that after @hClose@
279 has been performed, the ForeignObj embedded in the Handle
280 is still lying around in the heap, so care is taken
281 to avoid closing the file object when the ForeignObj
284 #ifndef __PARALLEL_HASKELL__
285 -- Mark the foreign object data value as
286 -- gone to the finaliser (freeFile())
287 writeForeignObj fp ``NULL''
289 writeHandle handle ClosedHandle
291 writeHandle handle htype
292 constructErrorAndFail "hClose"
294 else writeHandle handle htype
297 let fp = filePtr other
298 rc <- _ccall_ closeFile fp
300 #ifndef __PARALLEL_HASKELL__
301 -- Mark the foreign object data
302 writeForeignObj fp ``NULL''
304 writeHandle handle ClosedHandle
306 writeHandle handle htype
307 constructErrorAndFail "hClose"
310 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
311 computation finishes, any items buffered for output and not already
312 sent to the operating system are flushed as for $flush$.
314 %*********************************************************
316 \subsection[EOF]{Detecting the End of Input}
318 %*********************************************************
321 For a handle {\em hdl} which attached to a physical file, $hFileSize
322 hdl$ returns the size of {\em hdl} in terms of the number of items
323 which can be read from {\em hdl}.
326 hFileSize :: Handle -> IO Integer
327 hFileSize handle = do
328 htype <- readHandle handle
330 ErrorHandle ioError -> do
331 writeHandle handle htype
334 writeHandle handle htype
335 ioe_closedHandle handle
336 SemiClosedHandle _ _ -> do
337 writeHandle handle htype
338 ioe_closedHandle handle
340 -- HACK! We build a unique MP_INT of the right shape to hold
341 -- a single unsigned word, and we let the C routine
342 -- change the data bits
344 -- For some reason, this fails to typecheck if converted to a do
346 _casm_ ``%r = 1;'' >>= \(I# hack#) ->
347 case int2Integer# hack# of
348 result@(J# _ _ d#) -> do
349 let bogus_bounds = (error "fileSize"::(Int,Int))
350 rc <- _ccall_ fileSize (filePtr other)
351 (ByteArray bogus_bounds d#)
352 writeHandle handle htype
356 constructErrorAndFail "hFileSize"
359 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
360 $True$ if no further input can be taken from {\em hdl} or for a
361 physical file, if the current I/O position is equal to the length of
362 the file. Otherwise, it returns $False$.
365 hIsEOF :: Handle -> IO Bool
367 htype <- readHandle handle
369 ErrorHandle ioError -> do
370 writeHandle handle htype
373 writeHandle handle htype
374 ioe_closedHandle handle
375 SemiClosedHandle _ _ -> do
376 writeHandle handle htype
377 ioe_closedHandle handle
378 WriteHandle _ _ _ -> do
379 writeHandle handle htype
380 fail (IOError (Just handle) IllegalOperation
381 "handle is not open for reading")
382 AppendHandle _ _ _ -> do
383 writeHandle handle htype
384 fail (IOError (Just handle) IllegalOperation
385 "handle is not open for reading")
387 rc <- _ccall_ fileEOF (filePtr other)
388 writeHandle handle (markHandle htype)
392 _ -> constructErrorAndFail "hIsEOF"
398 %*********************************************************
400 \subsection[Buffering]{Buffering Operations}
402 %*********************************************************
404 Three kinds of buffering are supported: line-buffering,
405 block-buffering or no-buffering. See @IOBase@ for definition
406 and further explanation of what the type represent.
408 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
409 handle {\em hdl} on subsequent reads and writes.
413 If {\em mode} is @LineBuffering@, line-buffering should be
416 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
417 should be enabled if possible. The size of the buffer is {\em n} items
418 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
420 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
423 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
424 to @NoBuffering@, then any items in the output buffer are written to
425 the device, and any items in the input buffer are discarded. The
426 default buffering mode when a handle is opened is
427 implementation-dependent and may depend on the object which is
428 attached to that handle.
431 hSetBuffering :: Handle -> BufferMode -> IO ()
433 hSetBuffering handle mode =
435 BlockBuffering (Just n)
436 | n <= 0 -> fail (IOError (Just handle) InvalidArgument
437 "illegal buffer size")
439 htype <- readHandle handle
440 if isMarked htype then do
441 writeHandle handle htype
442 fail (IOError (Just handle)
444 "can't set buffering for a dirty handle")
447 ErrorHandle ioError -> do
448 writeHandle handle htype
451 writeHandle handle htype
452 ioe_closedHandle handle
453 SemiClosedHandle _ _ -> do
454 writeHandle handle htype
455 ioe_closedHandle handle
457 rc <- _ccall_ setBuffering (filePtr other) bsize
459 writeHandle handle ((hcon other) (filePtr other)
462 writeHandle handle htype
463 constructErrorAndFail "hSetBuffering"
466 isMarked :: Handle__ -> Bool
467 isMarked (ReadHandle fp m b) = b
468 isMarked (WriteHandle fp m b) = b
469 isMarked (AppendHandle fp m b) = b
470 isMarked (ReadWriteHandle fp m b) = b
477 BlockBuffering Nothing -> -2
478 BlockBuffering (Just n) -> n
480 #ifndef __PARALLEL_HASKELL__
481 hcon :: Handle__ -> (ForeignObj -> (Maybe BufferMode) -> Bool -> Handle__)
483 hcon :: Handle__ -> (Addr -> (Maybe BufferMode) -> Bool -> Handle__)
485 hcon (ReadHandle _ _ _) = ReadHandle
486 hcon (WriteHandle _ _ _) = WriteHandle
487 hcon (AppendHandle _ _ _) = AppendHandle
488 hcon (ReadWriteHandle _ _ _) = ReadWriteHandle
491 Computation $flush hdl$ causes any items buffered for output in handle
492 {\em hdl} to be sent immediately to the operating system.
495 hFlush :: Handle -> IO ()
497 htype <- readHandle handle
499 ErrorHandle ioError -> do
500 writeHandle handle htype
503 writeHandle handle htype
504 ioe_closedHandle handle
505 SemiClosedHandle _ _ -> do
506 writeHandle handle htype
507 ioe_closedHandle handle
509 rc <- _ccall_ flushFile (filePtr other)
510 writeHandle handle (markHandle htype)
514 constructErrorAndFail "hFlush"
518 %*********************************************************
520 \subsection[Seeking]{Repositioning Handles}
522 %*********************************************************
525 data HandlePosn = HandlePosn Handle Int
527 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
528 deriving (Eq, Ord, Ix, Enum, Read, Show)
531 Computation $hGetPosn hdl$ returns the current I/O
532 position of {\em hdl} as an abstract position. Computation
533 $hSetPosn p$ sets the position of {\em hdl}
534 to a previously obtained position {\em p}.
537 hGetPosn :: Handle -> IO HandlePosn
539 htype <- readHandle handle
541 ErrorHandle ioError -> do
542 writeHandle handle htype
545 writeHandle handle htype
546 ioe_closedHandle handle
547 SemiClosedHandle _ _ -> do
548 writeHandle handle htype
549 ioe_closedHandle handle
551 posn <- _ccall_ getFilePosn (filePtr other)
552 writeHandle handle htype
554 return (HandlePosn handle posn)
556 constructErrorAndFail "hGetPosn"
558 hSetPosn :: HandlePosn -> IO ()
559 hSetPosn (HandlePosn handle posn) = do
560 htype <- readHandle handle
562 ErrorHandle ioError -> do
563 writeHandle handle htype
566 writeHandle handle htype
567 ioe_closedHandle handle
568 SemiClosedHandle _ _ -> do
569 writeHandle handle htype
570 ioe_closedHandle handle
571 AppendHandle _ _ _ -> do
572 writeHandle handle htype
573 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
575 rc <- _ccall_ setFilePosn (filePtr other) posn
576 writeHandle handle (markHandle htype)
580 constructErrorAndFail "hSetPosn"
583 Computation $hSeek hdl mode i$ sets the position of handle
584 {\em hdl} depending on $mode$. If {\em mode} is
586 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
587 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
588 the current position.
589 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
591 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
592 the beginning of the file.
595 Some handles may not be seekable $hIsSeekable$, or only support a
596 subset of the possible positioning operations (e.g. it may only be
597 possible to seek to the end of a tape, or to a positive offset from
598 the beginning or current position).
600 It is not possible to set a negative I/O position, or for a physical
601 file, an I/O position beyond the current end-of-file.
604 hSeek :: Handle -> SeekMode -> Integer -> IO ()
605 hSeek handle mode offset@(J# _ s# d#) = do
606 htype <- readHandle handle
608 ErrorHandle ioError -> do
609 writeHandle handle htype
612 writeHandle handle htype
613 ioe_closedHandle handle
614 SemiClosedHandle _ _ -> do
615 writeHandle handle htype
616 ioe_closedHandle handle
617 AppendHandle _ _ _ -> do
618 writeHandle handle htype
619 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
621 rc <- _ccall_ seekFile (filePtr other) whence (I# s#)
623 writeHandle handle (markHandle htype)
627 constructErrorAndFail "hSeek"
630 whence = case mode of
631 AbsoluteSeek -> ``SEEK_SET''
632 RelativeSeek -> ``SEEK_CUR''
633 SeekFromEnd -> ``SEEK_END''
636 %*********************************************************
638 \subsection[Query]{Handle Properties}
640 %*********************************************************
642 A number of operations return information about the properties of a
643 handle. Each of these operations returns $True$ if the
644 handle has the specified property, and $False$
647 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
648 {\em hdl} is not block-buffered. Otherwise it returns
649 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
650 $( Just n )$ for block-buffering of {\em n} bytes.
653 hIsOpen :: Handle -> IO Bool
655 htype <- readHandle handle
657 ErrorHandle ioError -> do
658 writeHandle handle htype
661 writeHandle handle htype
663 SemiClosedHandle _ _ -> do
664 writeHandle handle htype
667 writeHandle handle htype
670 hIsClosed :: Handle -> IO Bool
671 hIsClosed handle = do
672 htype <- readHandle handle
674 ErrorHandle ioError -> do
675 writeHandle handle htype
678 writeHandle handle htype
681 writeHandle handle htype
684 hIsReadable :: Handle -> IO Bool
685 hIsReadable handle = do
686 htype <- readHandle handle
688 ErrorHandle ioError -> do
689 writeHandle handle htype
692 writeHandle handle htype
693 ioe_closedHandle handle
694 SemiClosedHandle _ _ -> do
695 writeHandle handle htype
696 ioe_closedHandle handle
698 writeHandle handle htype
699 return (isReadable other)
701 isReadable (ReadHandle _ _ _) = True
702 isReadable (ReadWriteHandle _ _ _) = True
705 hIsWritable :: Handle -> IO Bool
706 hIsWritable handle = do
707 htype <- readHandle handle
709 ErrorHandle ioError -> do
710 writeHandle handle htype
713 writeHandle handle htype
714 ioe_closedHandle handle
715 SemiClosedHandle _ _ -> do
716 writeHandle handle htype
717 ioe_closedHandle handle
719 writeHandle handle htype
720 return (isWritable other)
722 isWritable (AppendHandle _ _ _) = True
723 isWritable (WriteHandle _ _ _) = True
724 isWritable (ReadWriteHandle _ _ _) = True
727 getBufferMode :: Handle__ -> IO Handle__
728 getBufferMode htype =
729 case bufferMode htype of
730 Just x -> return htype
732 rc <- _ccall_ getBufferMode (filePtr htype)
736 0 -> Just NoBuffering
737 -1 -> Just LineBuffering
738 -2 -> Just (BlockBuffering Nothing)
740 n -> Just (BlockBuffering (Just n))
741 return (case htype of
742 ReadHandle fp _ b -> ReadHandle fp mode b
743 WriteHandle fp _ b -> WriteHandle fp mode b
744 AppendHandle fp _ b -> AppendHandle fp mode b
745 ReadWriteHandle fp _ b -> ReadWriteHandle fp mode b)
747 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
748 hIsBlockBuffered handle = do
749 htype <- readHandle handle
751 ErrorHandle ioError -> do
752 writeHandle handle htype
755 writeHandle handle htype
756 ioe_closedHandle handle
757 SemiClosedHandle _ _ -> do
758 writeHandle handle htype
759 ioe_closedHandle handle
761 other <- getBufferMode other
762 case bufferMode other of
763 Just (BlockBuffering size) -> do
764 writeHandle handle other
767 writeHandle handle other
768 return (False, Nothing)
770 constructErrorAndFail "hIsBlockBuffered"
772 hIsLineBuffered :: Handle -> IO Bool
773 hIsLineBuffered handle = do
774 htype <- readHandle handle
776 ErrorHandle ioError -> do
777 writeHandle handle htype
780 writeHandle handle htype
781 ioe_closedHandle handle
782 SemiClosedHandle _ _ -> do
783 writeHandle handle htype
784 ioe_closedHandle handle
786 other <- getBufferMode other
787 case bufferMode other of
788 Just LineBuffering -> do
789 writeHandle handle other
792 writeHandle handle other
795 constructErrorAndFail "hIsLineBuffered"
797 hIsNotBuffered :: Handle -> IO Bool
798 hIsNotBuffered handle = do
799 htype <- readHandle handle
801 ErrorHandle ioError -> do
802 writeHandle handle htype
805 writeHandle handle htype
806 ioe_closedHandle handle
807 SemiClosedHandle _ _ -> do
808 writeHandle handle htype
809 ioe_closedHandle handle
811 other <- getBufferMode other
812 case bufferMode other of
813 Just NoBuffering -> do
814 writeHandle handle other
817 writeHandle handle other
820 constructErrorAndFail "hIsNotBuffered"
822 hGetBuffering :: Handle -> IO BufferMode
823 hGetBuffering handle = do
824 htype <- readHandle handle
826 ErrorHandle ioError -> do
827 writeHandle handle htype
830 writeHandle handle htype
831 ioe_closedHandle handle
832 SemiClosedHandle _ _ -> do
833 writeHandle handle htype
834 ioe_closedHandle handle
836 other <- getBufferMode other
837 case bufferMode other of
839 writeHandle handle other
842 constructErrorAndFail "hGetBuffering"
844 hIsSeekable :: Handle -> IO Bool
845 hIsSeekable handle = do
846 htype <- readHandle handle
848 ErrorHandle ioError -> do
849 writeHandle handle htype
852 writeHandle handle htype
853 ioe_closedHandle handle
854 SemiClosedHandle _ _ -> do
855 writeHandle handle htype
856 ioe_closedHandle handle
857 AppendHandle _ _ _ -> do
858 writeHandle handle htype
861 rc <- _ccall_ seekFileP (filePtr other)
862 writeHandle handle htype
866 _ -> constructErrorAndFail "hIsSeekable"
870 %*********************************************************
872 \subsection{Miscellaneous}
874 %*********************************************************
876 These two functions are meant to get things out of @IOErrors@. They don't!
879 ioeGetFileName :: IOError -> Maybe FilePath
880 ioeGetErrorString :: IOError -> String
881 ioeGetHandle :: IOError -> Maybe Handle
883 ioeGetHandle (IOError h _ _) = h
884 ioeGetErrorString (IOError _ iot str) =
889 ioeGetFileName (IOError _ _ str) =
890 case span (/=':') str of
896 Internal function for creating an @IOError@ representing the
897 access of a closed file.
901 ioe_closedHandle :: Handle -> IO a
902 ioe_closedHandle h = fail (IOError (Just h) IllegalOperation "handle is closed")
905 A number of operations want to get at a readable or writeable handle, and fail
909 wantReadableHandle :: Handle -> IO Handle__
910 wantReadableHandle handle = do
911 htype <- readHandle handle
913 ErrorHandle ioError -> do
914 writeHandle handle htype
917 writeHandle handle htype
918 ioe_closedHandle handle
919 SemiClosedHandle _ _ -> do
920 writeHandle handle htype
921 ioe_closedHandle handle
922 AppendHandle _ _ _ -> do
923 writeHandle handle htype
924 fail (IOError (Just handle) IllegalOperation
925 "handle is not open for reading")
926 WriteHandle _ _ _ -> do
927 writeHandle handle htype
928 fail (IOError (Just handle) IllegalOperation
929 "handle is not open for reading")
930 other -> return other
932 wantWriteableHandle :: Handle
934 wantWriteableHandle handle = do
935 htype <- readHandle handle
937 ErrorHandle ioError -> do
938 writeHandle handle htype
941 writeHandle handle htype
942 ioe_closedHandle handle
943 SemiClosedHandle _ _ -> do
944 writeHandle handle htype
945 ioe_closedHandle handle
946 ReadHandle _ _ _ -> do
947 writeHandle handle htype
948 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
949 other -> return other