2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
4 \section[PrelStdIO]{Haskell 1.3 Standard I/O}
6 This module defines Haskell {\em handles} and the operations which are
9 Haskell interfaces to the external world through an abstract {\em file
10 system}. This file system is a collection of named {\em file system
11 objects}, which may be organised in {\em directories} (see
12 $LibDirectory$). In some implementations, directories may themselves
13 be file system objects and could be entries in other directories. For
14 simplicity, any non-directory file system object is termed a {\em
15 file}, although it could in fact be a communication channel, or any
16 other object recognised by the operating system.
18 File and directory names are values of type $String$, whose
19 precise meaning is operating system dependent. Files can be opened,
20 yielding a handle which can then be used to operate on the contents
23 \subsection[Handles]{Handles}
25 The standard defines operations to read/write finite sequences of
26 items from/to files, represented by values of type $Handle$. Each
27 value of this type is a {\em handle}: a record used by the Haskell
28 run-time system to {\em manage} I/O with operating system objects.
30 A handle has at least the following properties:
32 \item whether it manages input or output or both;
33 \item whether it is {\em open}, {\em closed} or {\em semi-closed};
34 \item the kind of object it manages;
35 \item if relevant, a current I/O position;
36 \item whether the object is seekable;
37 \item whether buffering is disabled, or enabled on a line or block basis;
38 \item a buffer (whose length may be zero).
41 A handle is {\em readable} if it manages only input or both input and
42 output; likewise, it is {\em writable} if it manages only output or
43 both input and output. A handle is {\em open} when first allocated.
44 Once it is closed it can no longer be used for either input or output,
45 though an implementation cannot re-use its storage while references
48 \subsubsection[SemiClosed]{Semi-Closed Handles}
50 The operation $hGetContents$ puts a handle {\em hdl}
51 into an intermediate state, {\em semi-closed}. In this state,
52 {\em hdl} is effectively closed, but items are read from
53 {\em hdl} on demand and accumulated in a special stream returned
54 by $hGetContents hdl$.
56 Any operation except for $hClose$ that fails because a handle is
57 closed, also fails if a handle is semi-closed. A semi-closed handle
60 \item if $hClose$ is applied to it;
61 \item if an I/O error occurs when reading an item from the
62 file item from the stream;
63 \item or once the entire contents of the file has been read.
66 Once a semi-closed handle becomes closed, the contents of the
67 associated stream becomes fixed, and is the list of those items which
68 were successfully read from that handle. Any I/O errors encountered
69 when a handle is semi-closed are simply discarded.
114 import PS ( _PackedString, _unpackPS )
115 import Prel ( otherwise, not, (.) )
117 import TyArray -- instance _CCallable (_ByteArray a)
119 import PreludeIOError
120 import PreludeMonadicIO
124 ---------------------------------
127 my_then :: IO a -> (a -> PrimIO b) -> PrimIO b
128 {-# INLINE my_then #-}
130 my_then m k = m `thenPrimIO` \ r -> k' r
133 k' (Left err) = error "my_then"
134 ---------------------------------
136 data Maybe a = Nothing | Just a {-partain-}deriving (Eq, Ord, Text)
138 data _Handle = _ErrorHandle IOError13
140 | _SemiClosedHandle _Addr (_Addr, Int)
141 | _ReadHandle _Addr (Maybe BufferMode) Bool
142 | _WriteHandle _Addr (Maybe BufferMode) Bool
143 | _AppendHandle _Addr (Maybe BufferMode) Bool
144 | _ReadWriteHandle _Addr (Maybe BufferMode) Bool
145 | _SocketHandle _Addr Bool
147 type Handle = _MVar _Handle
148 type FilePath = String
150 _filePtr :: _Handle -> _Addr
151 _filePtr (_SemiClosedHandle fp buf) = fp
152 _filePtr (_ReadHandle fp _ _) = fp
153 _filePtr (_WriteHandle fp _ _) = fp
154 _filePtr (_AppendHandle fp _ _) = fp
155 _filePtr (_ReadWriteHandle fp _ _) = fp
156 _filePtr (_SocketHandle fp _) = fp
158 _bufferMode :: _Handle -> Maybe BufferMode
159 _bufferMode (_ReadHandle _ m _) = m
160 _bufferMode (_WriteHandle _ m _) = m
161 _bufferMode (_AppendHandle _ m _) = m
162 _bufferMode (_ReadWriteHandle _ m _) = m
164 _markHandle :: _Handle -> _Handle
165 _markHandle h@(_ReadHandle fp m b)
167 | otherwise = _ReadHandle fp m True
168 _markHandle h@(_WriteHandle fp m b)
170 | otherwise = _WriteHandle fp m True
171 _markHandle h@(_AppendHandle fp m b)
173 | otherwise = _AppendHandle fp m True
174 _markHandle h@(_ReadWriteHandle fp m b)
176 | otherwise = _ReadWriteHandle fp m True
177 _markHandle h@(_SocketHandle fp b)
179 | otherwise = _SocketHandle fp True
183 \subsubsection[StandardHandles]{Standard Handles}
187 stdin13, stdout13, stderr13 :: Handle
189 stdin13 = unsafePerformPrimIO (
190 newEmptyMVar `my_then` \ handle ->
191 _ccall_ getLock (``stdin''::_Addr) 0 `thenPrimIO` \ rc ->
193 0 -> putMVar handle _ClosedHandle
194 1 -> putMVar handle (_ReadHandle ``stdin'' Nothing False)
195 _ -> _constructError `thenPrimIO` \ ioError ->
196 putMVar handle (_ErrorHandle ioError)
201 stdout13 = unsafePerformPrimIO (
202 newEmptyMVar `my_then` \ handle ->
203 _ccall_ getLock (``stdout''::_Addr) 1 `thenPrimIO` \ rc ->
205 0 -> putMVar handle _ClosedHandle
206 1 -> putMVar handle (_WriteHandle ``stdout'' Nothing False)
207 _ -> _constructError `thenPrimIO` \ ioError ->
208 putMVar handle (_ErrorHandle ioError)
213 stderr13 = unsafePerformPrimIO (
214 newEmptyMVar `my_then` \ handle ->
215 _ccall_ getLock (``stderr''::_Addr) 1 `thenPrimIO` \ rc ->
217 0 -> putMVar handle _ClosedHandle
218 1 -> putMVar handle (_WriteHandle ``stderr'' (Just NoBuffering) False)
219 _ -> _constructError `thenPrimIO` \ ioError ->
220 putMVar handle (_ErrorHandle ioError)
227 Three handles are allocated during program initialisation. The first
228 two manage input or output from the Haskell program's standard input
229 or output channel respectively. The third manages output to the
230 standard error channel. These handles are initially open.
232 \subsubsection[OpeningClosing]{Opening and Closing Files}
236 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
238 openFile :: FilePath -> IOMode -> IO Handle
241 _ccall_ openFile f m' `thenPrimIO` \ ptr ->
242 if ptr /= ``NULL'' then
243 newEmptyMVar >>= \ handle ->
244 putMVar handle (htype ptr Nothing False) >>
247 _constructError `thenPrimIO` \ ioError ->
249 improved_error -- a HACK, I guess
251 AlreadyExists msg -> AlreadyExists (msg ++ ": " ++ f)
252 NoSuchThing msg -> NoSuchThing (msg ++ ": " ++ f)
253 PermissionDenied msg -> PermissionDenied (msg ++ ": " ++ f)
256 failWith improved_error
262 ReadWriteMode -> "r+"
264 ReadMode -> _ReadHandle
265 WriteMode -> _WriteHandle
266 AppendMode -> _AppendHandle
267 ReadWriteMode -> _ReadWriteHandle
271 Computation $openFile file mode$ allocates and returns a new, open
272 handle to manage the file {\em file}. It manages input if {\em mode}
273 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
274 and both input and output if mode is $ReadWriteMode$.
276 If the file does not exist and it is opened for output, it should be
277 created as a new file. If {\em mode} is $WriteMode$ and the file
278 already exists, then it should be truncated to zero length. The
279 handle is positioned at the end of the file if {\em mode} is
280 $AppendMode$, and otherwise at the beginning (in which case its
281 internal position is 0).
283 Implementations should enforce, locally to the Haskell process,
284 multiple-reader single-writer locking on files, which is to say that
285 there may either be many handles on the same file which manage input,
286 or just one handle on the file which manages output. If any open or
287 semi-closed handle is managing a file for output, no new handle can be
288 allocated for that file. If any open or semi-closed handle is
289 managing a file for input, new handles can only be allocated if they
290 do not manage output.
292 Two files are the same if they have the same absolute name. An
293 implementation is free to impose stricter conditions.
297 hClose :: Handle -> IO ()
300 takeMVar handle >>= \ htype ->
301 putMVar handle _ClosedHandle >>
303 _ErrorHandle ioError ->
306 failWith (IllegalOperation "handle is closed")
307 _SemiClosedHandle fp (buf,_) ->
308 (if buf /= ``NULL'' then
311 returnPrimIO ()) `thenPrimIO` \ () ->
312 if fp /= ``NULL'' then
313 _ccall_ closeFile fp `thenPrimIO` \ rc ->
317 _constructError `thenPrimIO` \ ioError ->
322 _ccall_ closeFile (_filePtr other) `thenPrimIO` \ rc ->
326 _constructError `thenPrimIO` \ ioError ->
330 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
331 computation finishes, any items buffered for output and not already
332 sent to the operating system are flushed as for $flush$.
334 \subsubsection[EOF]{Detecting the End of Input}
338 hFileSize :: Handle -> IO Integer
341 takeMVar handle >>= \ htype ->
343 _ErrorHandle ioError ->
344 putMVar handle htype >>
347 putMVar handle htype >>
348 failWith (IllegalOperation "handle is closed")
349 _SemiClosedHandle _ _ ->
350 putMVar handle htype >>
351 failWith (IllegalOperation "handle is closed")
353 putMVar handle htype >>
354 failWith (IllegalOperation "socket handles have no size")
356 -- HACK! We build a unique MP_INT of the right shape to hold
357 -- a single unsigned word, and we let the C routine change the data bits
358 _casm_ ``%r = 1;'' `thenPrimIO` \ (I# hack#) ->
359 case int2Integer# hack# of
360 result@(J# _ _ d#) ->
361 _ccall_ fileSize (_filePtr other) (_ByteArray (error "fileSize") d#)
363 putMVar handle htype `seqPrimIO`
367 _constructError `thenPrimIO` \ ioError ->
372 For a handle {\em hdl} which attached to a physical file, $hFileSize
373 hdl$ returns the size of {\em hdl} in terms of the number of items
374 which can be read from {\em hdl}.
378 hIsEOF :: Handle -> IO Bool
380 takeMVar handle >>= \ htype ->
382 _ErrorHandle ioError ->
383 putMVar handle htype >>
386 putMVar handle htype >>
387 failWith (IllegalOperation "handle is closed")
388 _SemiClosedHandle _ _ ->
389 putMVar handle htype >>
390 failWith (IllegalOperation "handle is closed")
391 _WriteHandle _ _ _ ->
392 putMVar handle htype >>
393 failWith (IllegalOperation "handle is not open for reading")
394 _AppendHandle _ _ _ ->
395 putMVar handle htype >>
396 failWith (IllegalOperation "handle is not open for reading")
398 _ccall_ fileEOF (_filePtr other) `thenPrimIO` \ rc ->
399 putMVar handle (_markHandle htype) >>
403 _ -> _constructError `thenPrimIO` \ ioError ->
407 isEOF = hIsEOF stdin13
411 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
412 $True$ if no further input can be taken from {\em hdl} or for a
413 physical file, if the current I/O position is equal to the length of
414 the file. Otherwise, it returns $False$.
416 \subsubsection[Buffering]{Buffering Operations}
418 Three kinds of buffering are supported: line-buffering,
419 block-buffering or no-buffering. These modes have the following effects.
420 For output, items are written out from the internal buffer
421 according to the buffer mode:
423 \item[line-buffering] the entire output buffer is written
424 out whenever a newline is output, the output buffer overflows,
425 a flush is issued, or the handle is closed.
427 \item[block-buffering] the entire output buffer is written out whenever
428 it overflows, a flush is issued, or the handle
431 \item[no-buffering] output is written immediately, and never stored
432 in the output buffer.
435 The output buffer is emptied as soon as it has been written out.
437 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
439 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
440 the next item is obtained from the buffer;
441 otherwise, when the input buffer is empty,
442 characters up to and including the next newline
443 character are read into the buffer. No characters
444 are available until the newline character is
446 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
447 the next block of data is read into this buffer.
448 \item[no-buffering] the next input item is read and returned.
450 For most implementations, physical files will normally be block-buffered
451 and terminals will normally be line-buffered.
455 data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
457 hSetBuffering :: Handle -> BufferMode -> IO ()
459 hSetBuffering handle mode =
461 (BlockBuffering (Just n))
462 | n <= 0 -> failWith (InvalidArgument "illegal buffer size")
464 takeMVar handle >>= \ htype ->
465 if isMarked htype then
466 putMVar handle htype >>
467 failWith (UnsupportedOperation "can't set buffering for a dirty handle")
470 _ErrorHandle ioError ->
471 putMVar handle htype >>
474 putMVar handle htype >>
475 failWith (IllegalOperation "handle is closed")
476 _SemiClosedHandle _ _ ->
477 putMVar handle htype >>
478 failWith (IllegalOperation "handle is closed")
480 putMVar handle htype >>
481 failWith (IllegalOperation "buffering not supported for socket handles")
483 _ccall_ setBuffering (_filePtr other) bsize
486 putMVar handle ((hcon other) (_filePtr other) (Just mode) True)
490 putMVar handle htype >>
491 _constructError `thenPrimIO` \ ioError ->
495 isMarked :: _Handle -> Bool
496 isMarked (_ReadHandle fp m b) = b
497 isMarked (_WriteHandle fp m b) = b
498 isMarked (_AppendHandle fp m b) = b
499 isMarked (_ReadWriteHandle fp m b) = b
500 isMarked (_SocketHandle fp b) = b
506 BlockBuffering Nothing -> -2
507 BlockBuffering (Just n) -> n
509 hcon :: _Handle -> (_Addr -> (Maybe BufferMode) -> Bool -> _Handle)
510 hcon (_ReadHandle _ _ _) = _ReadHandle
511 hcon (_WriteHandle _ _ _) = _WriteHandle
512 hcon (_AppendHandle _ _ _) = _AppendHandle
513 hcon (_ReadWriteHandle _ _ _) = _ReadWriteHandle
517 Computation $hSetBuffering hdl mode$ sets the mode of buffering for
518 handle {\em hdl} on subsequent reads and writes.
522 If {\em mode} is $LineBuffering$, line-buffering should be
525 If {\em mode} is $BlockBuffering$ {\em size}, then block-buffering
526 should be enabled if possible. The size of the buffer is {\em n} items
527 if {\em size} is $Just${\em n} and is otherwise implementation-dependent.
529 If {\em mode} is $NoBuffering$, then buffering is disabled if possible.
532 If the buffer mode is changed from $BlockBuffering$ or $LineBuffering$
533 to $NoBuffering$, then any items in the output buffer are written to
534 the device, and any items in the input buffer are discarded. The
535 default buffering mode when a handle is opened is
536 implementation-dependent and may depend on the object which is
537 attached to that handle.
541 hFlush :: Handle -> IO ()
544 takeMVar handle >>= \ htype ->
546 _ErrorHandle ioError ->
547 putMVar handle htype >>
550 putMVar handle htype >>
551 failWith (IllegalOperation "handle is closed")
552 _SemiClosedHandle _ _ ->
553 putMVar handle htype >>
554 failWith (IllegalOperation "handle is closed")
556 putMVar handle htype >>
557 failWith (IllegalOperation "flush not supported for socket handles")
559 _ccall_ flushFile (_filePtr other) `thenPrimIO` \ rc ->
560 putMVar handle (_markHandle htype) >>
564 _constructError `thenPrimIO` \ ioError ->
569 Computation $flush hdl$ causes any items
570 buffered for output in handle {\em hdl} to be sent immediately to
571 the operating system.
573 \subsubsection[Seeking]{Repositioning Handles}
577 type HandlePosn = (Handle, Int)
579 hGetPosn :: Handle -> IO HandlePosn
581 takeMVar handle >>= \ htype ->
583 _ErrorHandle ioError ->
584 putMVar handle htype >>
587 putMVar handle htype >>
588 failWith (IllegalOperation "handle is closed")
589 _SemiClosedHandle _ _ ->
590 putMVar handle htype >>
591 failWith (IllegalOperation "handle is closed")
593 putMVar handle htype >>
594 failWith (IllegalOperation "position not supported for socket handles")
596 _ccall_ getFilePosn (_filePtr other) `thenPrimIO` \ posn ->
597 putMVar handle htype >>
599 return (handle, posn)
601 _constructError `thenPrimIO` \ ioError ->
604 hSetPosn :: HandlePosn -> IO ()
605 hSetPosn (handle, posn) =
606 takeMVar handle >>= \ htype ->
608 _ErrorHandle ioError ->
609 putMVar handle htype >>
612 putMVar handle htype >>
613 failWith (IllegalOperation "handle is closed")
614 _SemiClosedHandle _ _ ->
615 putMVar handle htype >>
616 failWith (IllegalOperation "handle is closed")
617 _AppendHandle _ _ _ ->
618 putMVar handle htype >>
619 failWith (IllegalOperation "handle is not seekable")
621 putMVar handle htype >>
622 failWith (IllegalOperation "seek not supported for socket handles")
624 _ccall_ setFilePosn (_filePtr other) posn `thenPrimIO` \ rc ->
625 putMVar handle (_markHandle htype) >>
629 _constructError `thenPrimIO` \ ioError ->
634 Computation $hGetPosn hdl$ returns the current I/O
635 position of {\em hdl} as an abstract position. Computation
636 $hSetPosn p$ sets the position of {\em hdl}
637 to a previously obtained position {\em p}.
641 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
643 hSeek :: Handle -> SeekMode -> Integer -> IO ()
644 hSeek handle mode offset@(J# _ s# d#) =
645 takeMVar handle >>= \ htype ->
647 _ErrorHandle ioError ->
648 putMVar handle htype >>
651 putMVar handle htype >>
652 failWith (IllegalOperation "handle is closed")
653 _SemiClosedHandle _ _ ->
654 putMVar handle htype >>
655 failWith (IllegalOperation "handle is closed")
656 _AppendHandle _ _ _ ->
657 putMVar handle htype >>
658 failWith (IllegalOperation "handle is not seekable")
660 putMVar handle htype >>
661 failWith (IllegalOperation "seek not supported for socket handles")
663 _ccall_ seekFile (_filePtr other) whence (I# s#) (_ByteArray (0,0) d#)
665 putMVar handle (_markHandle htype) >>
669 _constructError `thenPrimIO` \ ioError ->
673 whence = case mode of
674 AbsoluteSeek -> ``SEEK_SET''
675 RelativeSeek -> ``SEEK_CUR''
676 SeekFromEnd -> ``SEEK_END''
680 Computation $hSeek hdl mode i$ sets the position of handle
681 {\em hdl} depending on $mode$. If {\em mode} is
683 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
684 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
685 the current position.
686 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
688 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
689 the beginning of the file.
692 Some handles may not be seekable $hIsSeekable$, or only support a
693 subset of the possible positioning operations (e.g. it may only be
694 possible to seek to the end of a tape, or to a positive offset from
695 the beginning or current position).
697 It is not possible to set a negative I/O position, or for a physical
698 file, an I/O position beyond the current end-of-file.
700 \subsubsection[Query]{Handle Properties}
704 hIsOpen :: Handle -> IO Bool
706 takeMVar handle >>= \ htype ->
708 _ErrorHandle ioError ->
709 putMVar handle htype >>
712 putMVar handle htype >>
714 _SemiClosedHandle _ _ ->
715 putMVar handle htype >>
718 putMVar handle htype >>
721 hIsClosed :: Handle -> IO Bool
723 takeMVar handle >>= \ htype ->
725 _ErrorHandle ioError ->
726 putMVar handle htype >>
729 putMVar handle htype >>
732 putMVar handle htype >>
735 hIsReadable :: Handle -> IO Bool
737 takeMVar handle >>= \ htype ->
739 _ErrorHandle ioError ->
740 putMVar handle htype >>
743 putMVar handle htype >>
744 failWith (IllegalOperation "handle is closed")
745 _SemiClosedHandle _ _ ->
746 putMVar handle htype >>
747 failWith (IllegalOperation "handle is closed")
749 putMVar handle htype >>
750 return (isReadable other)
752 isReadable (_ReadHandle _ _ _) = True
753 isReadable (_ReadWriteHandle _ _ _) = True
754 isReadable (_SocketHandle _ _) = True
757 hIsWritable :: Handle -> IO Bool
759 takeMVar handle >>= \ htype ->
761 _ErrorHandle ioError ->
762 putMVar handle htype >>
765 putMVar handle htype >>
766 failWith (IllegalOperation "handle is closed")
767 _SemiClosedHandle _ _ ->
768 putMVar handle htype >>
769 failWith (IllegalOperation "handle is closed")
771 putMVar handle htype >>
772 return (isWritable other)
774 isWritable (_AppendHandle _ _ _) = True
775 isWritable (_WriteHandle _ _ _) = True
776 isWritable (_ReadWriteHandle _ _ _) = True
779 _getBufferMode :: _Handle -> PrimIO _Handle
780 _getBufferMode htype =
781 case _bufferMode htype of
782 Just x -> returnPrimIO htype
784 _ccall_ getBufferMode (_filePtr htype) `thenPrimIO` \ rc ->
788 0 -> Just NoBuffering
789 -1 -> Just LineBuffering
790 -2 -> Just (BlockBuffering Nothing)
792 n -> Just (BlockBuffering (Just n))
794 returnPrimIO (case htype of
795 _ReadHandle fp _ b -> _ReadHandle fp mode b
796 _WriteHandle fp _ b -> _WriteHandle fp mode b
797 _AppendHandle fp _ b -> _AppendHandle fp mode b
798 _ReadWriteHandle fp _ b -> _ReadWriteHandle fp mode b)
800 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
801 hIsBlockBuffered handle =
802 takeMVar handle >>= \ htype ->
804 _ErrorHandle ioError ->
805 putMVar handle htype >>
808 putMVar handle htype >>
809 failWith (IllegalOperation "handle is closed")
810 _SemiClosedHandle _ _ ->
811 putMVar handle htype >>
812 failWith (IllegalOperation "handle is closed")
814 _getBufferMode other `thenPrimIO` \ other ->
815 case _bufferMode other of
816 Just (BlockBuffering size) ->
817 putMVar handle other >>
820 putMVar handle other >>
821 return (False, Nothing)
823 _constructError `thenPrimIO` \ ioError ->
826 hIsLineBuffered :: Handle -> IO Bool
827 hIsLineBuffered handle =
828 takeMVar handle >>= \ htype ->
830 _ErrorHandle ioError ->
831 putMVar handle htype >>
834 putMVar handle htype >>
835 failWith (IllegalOperation "handle is closed")
836 _SemiClosedHandle _ _ ->
837 putMVar handle htype >>
838 failWith (IllegalOperation "handle is closed")
840 _getBufferMode other `thenPrimIO` \ other ->
841 case _bufferMode other of
842 Just LineBuffering ->
843 putMVar handle other >>
846 putMVar handle other >>
849 _constructError `thenPrimIO` \ ioError ->
852 hIsNotBuffered :: Handle -> IO Bool
853 hIsNotBuffered handle =
854 takeMVar handle >>= \ htype ->
856 _ErrorHandle ioError ->
857 putMVar handle htype >>
860 putMVar handle htype >>
861 failWith (IllegalOperation "handle is closed")
862 _SemiClosedHandle _ _ ->
863 putMVar handle htype >>
864 failWith (IllegalOperation "handle is closed")
866 _getBufferMode other `thenPrimIO` \ other ->
867 case _bufferMode other of
869 putMVar handle other >>
872 putMVar handle other >>
875 _constructError `thenPrimIO` \ ioError ->
878 hIsSeekable :: Handle -> IO Bool
880 takeMVar handle >>= \ htype ->
882 _ErrorHandle ioError ->
883 putMVar handle htype >>
886 putMVar handle htype >>
887 failWith (IllegalOperation "handle is closed")
888 _SemiClosedHandle _ _ ->
889 putMVar handle htype >>
890 failWith (IllegalOperation "handle is closed")
891 _AppendHandle _ _ _ ->
892 putMVar handle htype >>
895 putMVar handle htype >>
898 _ccall_ seekFileP (_filePtr other) `thenPrimIO` \ rc ->
899 putMVar handle htype >>
903 _ -> _constructError `thenPrimIO` \ ioError ->
909 A number of operations return information about the properties of a
910 handle. Each of these operations returns $True$ if the
911 handle has the specified property, and $False$
914 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
915 {\em hdl} is not block-buffered. Otherwise it returns
916 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
917 $( Just n )$ for block-buffering of {\em n} bytes.