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
163 _bufferMode (_SocketHandle _ _) = (Just NoBuffering)
165 _markHandle :: _Handle -> _Handle
166 _markHandle h@(_ReadHandle fp m b)
168 | otherwise = _ReadHandle fp m True
169 _markHandle h@(_WriteHandle fp m b)
171 | otherwise = _WriteHandle fp m True
172 _markHandle h@(_AppendHandle fp m b)
174 | otherwise = _AppendHandle fp m True
175 _markHandle h@(_ReadWriteHandle fp m b)
177 | otherwise = _ReadWriteHandle fp m True
178 _markHandle h@(_SocketHandle fp b)
180 | otherwise = _SocketHandle fp True
184 \subsubsection[StandardHandles]{Standard Handles}
188 stdin13, stdout13, stderr13 :: Handle
190 stdin13 = unsafePerformPrimIO (
191 newEmptyMVar `my_then` \ handle ->
192 _ccall_ getLock (``stdin''::_Addr) 0 `thenPrimIO` \ rc ->
194 0 -> putMVar handle _ClosedHandle
195 1 -> putMVar handle (_ReadHandle ``stdin'' Nothing False)
196 _ -> _constructError `thenPrimIO` \ ioError ->
197 putMVar handle (_ErrorHandle ioError)
202 stdout13 = unsafePerformPrimIO (
203 newEmptyMVar `my_then` \ handle ->
204 _ccall_ getLock (``stdout''::_Addr) 1 `thenPrimIO` \ rc ->
206 0 -> putMVar handle _ClosedHandle
207 1 -> putMVar handle (_WriteHandle ``stdout'' Nothing False)
208 _ -> _constructError `thenPrimIO` \ ioError ->
209 putMVar handle (_ErrorHandle ioError)
214 stderr13 = unsafePerformPrimIO (
215 newEmptyMVar `my_then` \ handle ->
216 _ccall_ getLock (``stderr''::_Addr) 1 `thenPrimIO` \ rc ->
218 0 -> putMVar handle _ClosedHandle
219 1 -> putMVar handle (_WriteHandle ``stderr'' (Just NoBuffering) False)
220 _ -> _constructError `thenPrimIO` \ ioError ->
221 putMVar handle (_ErrorHandle ioError)
228 Three handles are allocated during program initialisation. The first
229 two manage input or output from the Haskell program's standard input
230 or output channel respectively. The third manages output to the
231 standard error channel. These handles are initially open.
233 \subsubsection[OpeningClosing]{Opening and Closing Files}
237 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
239 openFile :: FilePath -> IOMode -> IO Handle
242 _ccall_ openFile f m' `thenPrimIO` \ ptr ->
243 if ptr /= ``NULL'' then
244 newEmptyMVar >>= \ handle ->
245 putMVar handle (htype ptr Nothing False) >>
248 _constructError `thenPrimIO` \ ioError ->
250 improved_error -- a HACK, I guess
252 AlreadyExists msg -> AlreadyExists (msg ++ ": " ++ f)
253 NoSuchThing msg -> NoSuchThing (msg ++ ": " ++ f)
254 PermissionDenied msg -> PermissionDenied (msg ++ ": " ++ f)
257 failWith improved_error
263 ReadWriteMode -> "r+"
265 ReadMode -> _ReadHandle
266 WriteMode -> _WriteHandle
267 AppendMode -> _AppendHandle
268 ReadWriteMode -> _ReadWriteHandle
272 Computation $openFile file mode$ allocates and returns a new, open
273 handle to manage the file {\em file}. It manages input if {\em mode}
274 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
275 and both input and output if mode is $ReadWriteMode$.
277 If the file does not exist and it is opened for output, it should be
278 created as a new file. If {\em mode} is $WriteMode$ and the file
279 already exists, then it should be truncated to zero length. The
280 handle is positioned at the end of the file if {\em mode} is
281 $AppendMode$, and otherwise at the beginning (in which case its
282 internal position is 0).
284 Implementations should enforce, locally to the Haskell process,
285 multiple-reader single-writer locking on files, which is to say that
286 there may either be many handles on the same file which manage input,
287 or just one handle on the file which manages output. If any open or
288 semi-closed handle is managing a file for output, no new handle can be
289 allocated for that file. If any open or semi-closed handle is
290 managing a file for input, new handles can only be allocated if they
291 do not manage output.
293 Two files are the same if they have the same absolute name. An
294 implementation is free to impose stricter conditions.
298 hClose :: Handle -> IO ()
301 takeMVar handle >>= \ htype ->
302 putMVar handle _ClosedHandle >>
304 _ErrorHandle ioError ->
307 failWith (IllegalOperation "handle is closed")
308 _SemiClosedHandle fp (buf,_) ->
309 (if buf /= ``NULL'' then
312 returnPrimIO ()) `thenPrimIO` \ () ->
313 if fp /= ``NULL'' then
314 _ccall_ closeFile fp `thenPrimIO` \ rc ->
318 _constructError `thenPrimIO` \ ioError ->
323 _ccall_ closeFile (_filePtr other) `thenPrimIO` \ rc ->
327 _constructError `thenPrimIO` \ ioError ->
331 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
332 computation finishes, any items buffered for output and not already
333 sent to the operating system are flushed as for $flush$.
335 \subsubsection[EOF]{Detecting the End of Input}
339 hFileSize :: Handle -> IO Integer
342 takeMVar handle >>= \ htype ->
344 _ErrorHandle ioError ->
345 putMVar handle htype >>
348 putMVar handle htype >>
349 failWith (IllegalOperation "handle is closed")
350 _SemiClosedHandle _ _ ->
351 putMVar handle htype >>
352 failWith (IllegalOperation "handle is closed")
354 putMVar handle htype >>
355 failWith (IllegalOperation "socket handles have no size")
357 -- HACK! We build a unique MP_INT of the right shape to hold
358 -- a single unsigned word, and we let the C routine change the data bits
359 _casm_ ``%r = 1;'' `thenPrimIO` \ (I# hack#) ->
360 case int2Integer# hack# of
361 result@(J# _ _ d#) ->
362 _ccall_ fileSize (_filePtr other) (_ByteArray (error "fileSize") d#)
364 putMVar handle htype `seqPrimIO`
368 _constructError `thenPrimIO` \ ioError ->
373 For a handle {\em hdl} which attached to a physical file, $hFileSize
374 hdl$ returns the size of {\em hdl} in terms of the number of items
375 which can be read from {\em hdl}.
379 hIsEOF :: Handle -> IO Bool
381 takeMVar handle >>= \ htype ->
383 _ErrorHandle ioError ->
384 putMVar handle htype >>
387 putMVar handle htype >>
388 failWith (IllegalOperation "handle is closed")
389 _SemiClosedHandle _ _ ->
390 putMVar handle htype >>
391 failWith (IllegalOperation "handle is closed")
392 _WriteHandle _ _ _ ->
393 putMVar handle htype >>
394 failWith (IllegalOperation "handle is not open for reading")
395 _AppendHandle _ _ _ ->
396 putMVar handle htype >>
397 failWith (IllegalOperation "handle is not open for reading")
399 _ccall_ fileEOF (_filePtr other) `thenPrimIO` \ rc ->
400 putMVar handle (_markHandle htype) >>
404 _ -> _constructError `thenPrimIO` \ ioError ->
408 isEOF = hIsEOF stdin13
412 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
413 $True$ if no further input can be taken from {\em hdl} or for a
414 physical file, if the current I/O position is equal to the length of
415 the file. Otherwise, it returns $False$.
417 \subsubsection[Buffering]{Buffering Operations}
419 Three kinds of buffering are supported: line-buffering,
420 block-buffering or no-buffering. These modes have the following effects.
421 For output, items are written out from the internal buffer
422 according to the buffer mode:
424 \item[line-buffering] the entire output buffer is written
425 out whenever a newline is output, the output buffer overflows,
426 a flush is issued, or the handle is closed.
428 \item[block-buffering] the entire output buffer is written out whenever
429 it overflows, a flush is issued, or the handle
432 \item[no-buffering] output is written immediately, and never stored
433 in the output buffer.
436 The output buffer is emptied as soon as it has been written out.
438 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
440 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
441 the next item is obtained from the buffer;
442 otherwise, when the input buffer is empty,
443 characters up to and including the next newline
444 character are read into the buffer. No characters
445 are available until the newline character is
447 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
448 the next block of data is read into this buffer.
449 \item[no-buffering] the next input item is read and returned.
451 For most implementations, physical files will normally be block-buffered
452 and terminals will normally be line-buffered.
456 data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
458 hSetBuffering :: Handle -> BufferMode -> IO ()
460 hSetBuffering handle mode =
462 (BlockBuffering (Just n))
463 | n <= 0 -> failWith (InvalidArgument "illegal buffer size")
465 takeMVar handle >>= \ htype ->
466 if isMarked htype then
467 putMVar handle htype >>
468 failWith (UnsupportedOperation "can't set buffering for a dirty handle")
471 _ErrorHandle ioError ->
472 putMVar handle htype >>
475 putMVar handle htype >>
476 failWith (IllegalOperation "handle is closed")
477 _SemiClosedHandle _ _ ->
478 putMVar handle htype >>
479 failWith (IllegalOperation "handle is closed")
482 putMVar handle htype >>
483 failWith (IllegalOperation "buffering not supported for socket handles")
486 _ccall_ setBuffering (_filePtr other) bsize
489 putMVar handle ((hcon other) (_filePtr other) (Just mode) True)
493 putMVar handle htype >>
494 _constructError `thenPrimIO` \ ioError ->
498 isMarked :: _Handle -> Bool
499 isMarked (_ReadHandle fp m b) = b
500 isMarked (_WriteHandle fp m b) = b
501 isMarked (_AppendHandle fp m b) = b
502 isMarked (_ReadWriteHandle fp m b) = b
503 isMarked (_SocketHandle fp b) = b
509 BlockBuffering Nothing -> -2
510 BlockBuffering (Just n) -> n
512 hcon :: _Handle -> (_Addr -> (Maybe BufferMode) -> Bool -> _Handle)
513 hcon (_ReadHandle _ _ _) = _ReadHandle
514 hcon (_WriteHandle _ _ _) = _WriteHandle
515 hcon (_AppendHandle _ _ _) = _AppendHandle
516 hcon (_ReadWriteHandle _ _ _) = _ReadWriteHandle
517 hcon (_SocketHandle _ _) = \ a _ v -> _SocketHandle a v
521 Computation $hSetBuffering hdl mode$ sets the mode of buffering for
522 handle {\em hdl} on subsequent reads and writes.
526 If {\em mode} is $LineBuffering$, line-buffering should be
529 If {\em mode} is $BlockBuffering$ {\em size}, then block-buffering
530 should be enabled if possible. The size of the buffer is {\em n} items
531 if {\em size} is $Just${\em n} and is otherwise implementation-dependent.
533 If {\em mode} is $NoBuffering$, then buffering is disabled if possible.
536 If the buffer mode is changed from $BlockBuffering$ or $LineBuffering$
537 to $NoBuffering$, then any items in the output buffer are written to
538 the device, and any items in the input buffer are discarded. The
539 default buffering mode when a handle is opened is
540 implementation-dependent and may depend on the object which is
541 attached to that handle.
545 hFlush :: Handle -> IO ()
548 takeMVar handle >>= \ htype ->
550 _ErrorHandle ioError ->
551 putMVar handle htype >>
554 putMVar handle htype >>
555 failWith (IllegalOperation "handle is closed")
556 _SemiClosedHandle _ _ ->
557 putMVar handle htype >>
558 failWith (IllegalOperation "handle is closed")
560 putMVar handle htype >>
561 failWith (IllegalOperation "flush not supported for socket handles")
563 _ccall_ flushFile (_filePtr other) `thenPrimIO` \ rc ->
564 putMVar handle (_markHandle htype) >>
568 _constructError `thenPrimIO` \ ioError ->
573 Computation $flush hdl$ causes any items
574 buffered for output in handle {\em hdl} to be sent immediately to
575 the operating system.
577 \subsubsection[Seeking]{Repositioning Handles}
581 type HandlePosn = (Handle, Int)
583 hGetPosn :: Handle -> IO HandlePosn
585 takeMVar handle >>= \ htype ->
587 _ErrorHandle ioError ->
588 putMVar handle htype >>
591 putMVar handle htype >>
592 failWith (IllegalOperation "handle is closed")
593 _SemiClosedHandle _ _ ->
594 putMVar handle htype >>
595 failWith (IllegalOperation "handle is closed")
597 putMVar handle htype >>
598 failWith (IllegalOperation "position not supported for socket handles")
600 _ccall_ getFilePosn (_filePtr other) `thenPrimIO` \ posn ->
601 putMVar handle htype >>
603 return (handle, posn)
605 _constructError `thenPrimIO` \ ioError ->
608 hSetPosn :: HandlePosn -> IO ()
609 hSetPosn (handle, posn) =
610 takeMVar handle >>= \ htype ->
612 _ErrorHandle ioError ->
613 putMVar handle htype >>
616 putMVar handle htype >>
617 failWith (IllegalOperation "handle is closed")
618 _SemiClosedHandle _ _ ->
619 putMVar handle htype >>
620 failWith (IllegalOperation "handle is closed")
621 _AppendHandle _ _ _ ->
622 putMVar handle htype >>
623 failWith (IllegalOperation "handle is not seekable")
625 putMVar handle htype >>
626 failWith (IllegalOperation "seek not supported for socket handles")
628 _ccall_ setFilePosn (_filePtr other) posn `thenPrimIO` \ rc ->
629 putMVar handle (_markHandle htype) >>
633 _constructError `thenPrimIO` \ ioError ->
638 Computation $hGetPosn hdl$ returns the current I/O
639 position of {\em hdl} as an abstract position. Computation
640 $hSetPosn p$ sets the position of {\em hdl}
641 to a previously obtained position {\em p}.
645 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
647 hSeek :: Handle -> SeekMode -> Integer -> IO ()
648 hSeek handle mode offset@(J# _ s# d#) =
649 takeMVar handle >>= \ htype ->
651 _ErrorHandle ioError ->
652 putMVar handle htype >>
655 putMVar handle htype >>
656 failWith (IllegalOperation "handle is closed")
657 _SemiClosedHandle _ _ ->
658 putMVar handle htype >>
659 failWith (IllegalOperation "handle is closed")
660 _AppendHandle _ _ _ ->
661 putMVar handle htype >>
662 failWith (IllegalOperation "handle is not seekable")
664 putMVar handle htype >>
665 failWith (IllegalOperation "seek not supported for socket handles")
667 _ccall_ seekFile (_filePtr other) whence (I# s#) (_ByteArray (0,0) d#)
669 putMVar handle (_markHandle htype) >>
673 _constructError `thenPrimIO` \ ioError ->
677 whence = case mode of
678 AbsoluteSeek -> ``SEEK_SET''
679 RelativeSeek -> ``SEEK_CUR''
680 SeekFromEnd -> ``SEEK_END''
684 Computation $hSeek hdl mode i$ sets the position of handle
685 {\em hdl} depending on $mode$. If {\em mode} is
687 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
688 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
689 the current position.
690 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
692 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
693 the beginning of the file.
696 Some handles may not be seekable $hIsSeekable$, or only support a
697 subset of the possible positioning operations (e.g. it may only be
698 possible to seek to the end of a tape, or to a positive offset from
699 the beginning or current position).
701 It is not possible to set a negative I/O position, or for a physical
702 file, an I/O position beyond the current end-of-file.
704 \subsubsection[Query]{Handle Properties}
708 hIsOpen :: Handle -> IO Bool
710 takeMVar handle >>= \ htype ->
712 _ErrorHandle ioError ->
713 putMVar handle htype >>
716 putMVar handle htype >>
718 _SemiClosedHandle _ _ ->
719 putMVar handle htype >>
722 putMVar handle htype >>
725 hIsClosed :: Handle -> IO Bool
727 takeMVar handle >>= \ htype ->
729 _ErrorHandle ioError ->
730 putMVar handle htype >>
733 putMVar handle htype >>
736 putMVar handle htype >>
739 hIsReadable :: Handle -> IO Bool
741 takeMVar handle >>= \ htype ->
743 _ErrorHandle ioError ->
744 putMVar handle htype >>
747 putMVar handle htype >>
748 failWith (IllegalOperation "handle is closed")
749 _SemiClosedHandle _ _ ->
750 putMVar handle htype >>
751 failWith (IllegalOperation "handle is closed")
753 putMVar handle htype >>
754 return (isReadable other)
756 isReadable (_ReadHandle _ _ _) = True
757 isReadable (_ReadWriteHandle _ _ _) = True
758 isReadable (_SocketHandle _ _) = True
761 hIsWritable :: Handle -> IO Bool
763 takeMVar handle >>= \ htype ->
765 _ErrorHandle ioError ->
766 putMVar handle htype >>
769 putMVar handle htype >>
770 failWith (IllegalOperation "handle is closed")
771 _SemiClosedHandle _ _ ->
772 putMVar handle htype >>
773 failWith (IllegalOperation "handle is closed")
775 putMVar handle htype >>
776 return (isWritable other)
778 isWritable (_AppendHandle _ _ _) = True
779 isWritable (_WriteHandle _ _ _) = True
780 isWritable (_ReadWriteHandle _ _ _) = True
783 _getBufferMode :: _Handle -> PrimIO _Handle
784 _getBufferMode htype =
785 case _bufferMode htype of
786 Just x -> returnPrimIO htype
788 _ccall_ getBufferMode (_filePtr htype) `thenPrimIO` \ rc ->
792 0 -> Just NoBuffering
793 -1 -> Just LineBuffering
794 -2 -> Just (BlockBuffering Nothing)
796 n -> Just (BlockBuffering (Just n))
798 returnPrimIO (case htype of
799 _ReadHandle fp _ b -> _ReadHandle fp mode b
800 _WriteHandle fp _ b -> _WriteHandle fp mode b
801 _AppendHandle fp _ b -> _AppendHandle fp mode b
802 _ReadWriteHandle fp _ b -> _ReadWriteHandle fp mode b)
804 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
805 hIsBlockBuffered handle =
806 takeMVar handle >>= \ htype ->
808 _ErrorHandle ioError ->
809 putMVar handle htype >>
812 putMVar handle htype >>
813 failWith (IllegalOperation "handle is closed")
814 _SemiClosedHandle _ _ ->
815 putMVar handle htype >>
816 failWith (IllegalOperation "handle is closed")
818 _getBufferMode other `thenPrimIO` \ other ->
819 case _bufferMode other of
820 Just (BlockBuffering size) ->
821 putMVar handle other >>
824 putMVar handle other >>
825 return (False, Nothing)
827 _constructError `thenPrimIO` \ ioError ->
830 hIsLineBuffered :: Handle -> IO Bool
831 hIsLineBuffered handle =
832 takeMVar handle >>= \ htype ->
834 _ErrorHandle ioError ->
835 putMVar handle htype >>
838 putMVar handle htype >>
839 failWith (IllegalOperation "handle is closed")
840 _SemiClosedHandle _ _ ->
841 putMVar handle htype >>
842 failWith (IllegalOperation "handle is closed")
844 _getBufferMode other `thenPrimIO` \ other ->
845 case _bufferMode other of
846 Just LineBuffering ->
847 putMVar handle other >>
850 putMVar handle other >>
853 _constructError `thenPrimIO` \ ioError ->
856 hIsNotBuffered :: Handle -> IO Bool
857 hIsNotBuffered handle =
858 takeMVar handle >>= \ htype ->
860 _ErrorHandle ioError ->
861 putMVar handle htype >>
864 putMVar handle htype >>
865 failWith (IllegalOperation "handle is closed")
866 _SemiClosedHandle _ _ ->
867 putMVar handle htype >>
868 failWith (IllegalOperation "handle is closed")
870 _getBufferMode other `thenPrimIO` \ other ->
871 case _bufferMode other of
873 putMVar handle other >>
876 putMVar handle other >>
879 _constructError `thenPrimIO` \ ioError ->
882 hIsSeekable :: Handle -> IO Bool
884 takeMVar handle >>= \ htype ->
886 _ErrorHandle ioError ->
887 putMVar handle htype >>
890 putMVar handle htype >>
891 failWith (IllegalOperation "handle is closed")
892 _SemiClosedHandle _ _ ->
893 putMVar handle htype >>
894 failWith (IllegalOperation "handle is closed")
895 _AppendHandle _ _ _ ->
896 putMVar handle htype >>
899 putMVar handle htype >>
902 _ccall_ seekFileP (_filePtr other) `thenPrimIO` \ rc ->
903 putMVar handle htype >>
907 _ -> _constructError `thenPrimIO` \ ioError ->
913 A number of operations return information about the properties of a
914 handle. Each of these operations returns $True$ if the
915 handle has the specified property, and $False$
918 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
919 {\em hdl} is not block-buffered. Otherwise it returns
920 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
921 $( Just n )$ for block-buffering of {\em n} bytes.