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)
120 import PreludeIOError
121 import PreludeMonadicIO
125 ---------------------------------
128 my_then :: IO a -> (a -> PrimIO b) -> PrimIO b
129 {-# INLINE my_then #-}
131 my_then m k = m `thenPrimIO` \ r -> k' r
134 k' (Left err) = error "my_then"
135 ---------------------------------
137 data Maybe a = Nothing | Just a {-partain-}deriving (Eq, Ord, Text)
139 data _Handle = _ErrorHandle IOError13
141 | _SemiClosedHandle _Addr (_Addr, Int)
142 | _ReadHandle _Addr (Maybe BufferMode) Bool
143 | _WriteHandle _Addr (Maybe BufferMode) Bool
144 | _AppendHandle _Addr (Maybe BufferMode) Bool
145 | _ReadWriteHandle _Addr (Maybe BufferMode) Bool
146 | _SocketHandle _Addr Bool
148 type Handle = _MVar _Handle
149 type FilePath = String
151 _filePtr :: _Handle -> _Addr
152 _filePtr (_SemiClosedHandle fp buf) = fp
153 _filePtr (_ReadHandle fp _ _) = fp
154 _filePtr (_WriteHandle fp _ _) = fp
155 _filePtr (_AppendHandle fp _ _) = fp
156 _filePtr (_ReadWriteHandle fp _ _) = fp
157 _filePtr (_SocketHandle fp _) = fp
159 _bufferMode :: _Handle -> Maybe BufferMode
160 _bufferMode (_ReadHandle _ m _) = m
161 _bufferMode (_WriteHandle _ m _) = m
162 _bufferMode (_AppendHandle _ m _) = m
163 _bufferMode (_ReadWriteHandle _ m _) = m
164 _bufferMode (_SocketHandle _ _) = (Just NoBuffering)
166 _markHandle :: _Handle -> _Handle
167 _markHandle h@(_ReadHandle fp m b)
169 | otherwise = _ReadHandle fp m True
170 _markHandle h@(_WriteHandle fp m b)
172 | otherwise = _WriteHandle fp m True
173 _markHandle h@(_AppendHandle fp m b)
175 | otherwise = _AppendHandle fp m True
176 _markHandle h@(_ReadWriteHandle fp m b)
178 | otherwise = _ReadWriteHandle fp m True
179 _markHandle h@(_SocketHandle fp b)
181 | otherwise = _SocketHandle fp True
185 \subsubsection[StandardHandles]{Standard Handles}
189 stdin13, stdout13, stderr13 :: Handle
191 stdin13 = unsafePerformPrimIO (
192 newEmptyMVar `my_then` \ handle ->
193 _ccall_ getLock (``stdin''::_Addr) 0 `thenPrimIO` \ rc ->
195 0 -> putMVar handle _ClosedHandle
196 1 -> putMVar handle (_ReadHandle ``stdin'' Nothing False)
197 _ -> _constructError `thenPrimIO` \ ioError ->
198 putMVar handle (_ErrorHandle ioError)
203 stdout13 = unsafePerformPrimIO (
204 newEmptyMVar `my_then` \ handle ->
205 _ccall_ getLock (``stdout''::_Addr) 1 `thenPrimIO` \ rc ->
207 0 -> putMVar handle _ClosedHandle
208 1 -> putMVar handle (_WriteHandle ``stdout'' Nothing False)
209 _ -> _constructError `thenPrimIO` \ ioError ->
210 putMVar handle (_ErrorHandle ioError)
215 stderr13 = unsafePerformPrimIO (
216 newEmptyMVar `my_then` \ handle ->
217 _ccall_ getLock (``stderr''::_Addr) 1 `thenPrimIO` \ rc ->
219 0 -> putMVar handle _ClosedHandle
220 1 -> putMVar handle (_WriteHandle ``stderr'' (Just NoBuffering) False)
221 _ -> _constructError `thenPrimIO` \ ioError ->
222 putMVar handle (_ErrorHandle ioError)
229 Three handles are allocated during program initialisation. The first
230 two manage input or output from the Haskell program's standard input
231 or output channel respectively. The third manages output to the
232 standard error channel. These handles are initially open.
234 \subsubsection[OpeningClosing]{Opening and Closing Files}
238 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
240 openFile :: FilePath -> IOMode -> IO Handle
243 _ccall_ openFile f m' `thenPrimIO` \ ptr ->
244 if ptr /= ``NULL'' then
245 newEmptyMVar >>= \ handle ->
246 putMVar handle (htype ptr Nothing False) >>
249 _constructError `thenPrimIO` \ ioError ->
251 improved_error -- a HACK, I guess
253 AlreadyExists msg -> AlreadyExists (msg ++ ": " ++ f)
254 NoSuchThing msg -> NoSuchThing (msg ++ ": " ++ f)
255 PermissionDenied msg -> PermissionDenied (msg ++ ": " ++ f)
258 failWith improved_error
264 ReadWriteMode -> "r+"
266 ReadMode -> _ReadHandle
267 WriteMode -> _WriteHandle
268 AppendMode -> _AppendHandle
269 ReadWriteMode -> _ReadWriteHandle
273 Computation $openFile file mode$ allocates and returns a new, open
274 handle to manage the file {\em file}. It manages input if {\em mode}
275 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
276 and both input and output if mode is $ReadWriteMode$.
278 If the file does not exist and it is opened for output, it should be
279 created as a new file. If {\em mode} is $WriteMode$ and the file
280 already exists, then it should be truncated to zero length. The
281 handle is positioned at the end of the file if {\em mode} is
282 $AppendMode$, and otherwise at the beginning (in which case its
283 internal position is 0).
285 Implementations should enforce, locally to the Haskell process,
286 multiple-reader single-writer locking on files, which is to say that
287 there may either be many handles on the same file which manage input,
288 or just one handle on the file which manages output. If any open or
289 semi-closed handle is managing a file for output, no new handle can be
290 allocated for that file. If any open or semi-closed handle is
291 managing a file for input, new handles can only be allocated if they
292 do not manage output.
294 Two files are the same if they have the same absolute name. An
295 implementation is free to impose stricter conditions.
299 hClose :: Handle -> IO ()
302 takeMVar handle >>= \ htype ->
303 putMVar handle _ClosedHandle >>
305 _ErrorHandle ioError ->
308 failWith (IllegalOperation "handle is closed")
309 _SemiClosedHandle fp (buf,_) ->
310 (if buf /= ``NULL'' then
313 returnPrimIO ()) `thenPrimIO` \ () ->
314 if fp /= ``NULL'' then
315 _ccall_ closeFile fp `thenPrimIO` \ rc ->
319 _constructError `thenPrimIO` \ ioError ->
324 _ccall_ closeFile (_filePtr other) `thenPrimIO` \ rc ->
328 _constructError `thenPrimIO` \ ioError ->
332 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
333 computation finishes, any items buffered for output and not already
334 sent to the operating system are flushed as for $flush$.
336 \subsubsection[EOF]{Detecting the End of Input}
340 hFileSize :: Handle -> IO Integer
343 takeMVar handle >>= \ htype ->
345 _ErrorHandle ioError ->
346 putMVar handle htype >>
349 putMVar handle htype >>
350 failWith (IllegalOperation "handle is closed")
351 _SemiClosedHandle _ _ ->
352 putMVar handle htype >>
353 failWith (IllegalOperation "handle is closed")
355 putMVar handle htype >>
356 failWith (IllegalOperation "socket handles have no size")
358 -- HACK! We build a unique MP_INT of the right shape to hold
359 -- a single unsigned word, and we let the C routine change the data bits
360 _casm_ ``%r = 1;'' `thenPrimIO` \ (I# hack#) ->
361 case int2Integer# hack# of
362 result@(J# _ _ d#) ->
363 _ccall_ fileSize (_filePtr other) (_ByteArray (error "fileSize") d#)
365 putMVar handle htype `seqPrimIO`
369 _constructError `thenPrimIO` \ ioError ->
374 For a handle {\em hdl} which attached to a physical file, $hFileSize
375 hdl$ returns the size of {\em hdl} in terms of the number of items
376 which can be read from {\em hdl}.
380 hIsEOF :: Handle -> IO Bool
382 takeMVar handle >>= \ htype ->
384 _ErrorHandle ioError ->
385 putMVar handle htype >>
388 putMVar handle htype >>
389 failWith (IllegalOperation "handle is closed")
390 _SemiClosedHandle _ _ ->
391 putMVar handle htype >>
392 failWith (IllegalOperation "handle is closed")
393 _WriteHandle _ _ _ ->
394 putMVar handle htype >>
395 failWith (IllegalOperation "handle is not open for reading")
396 _AppendHandle _ _ _ ->
397 putMVar handle htype >>
398 failWith (IllegalOperation "handle is not open for reading")
400 _ccall_ fileEOF (_filePtr other) `thenPrimIO` \ rc ->
401 putMVar handle (_markHandle htype) >>
405 _ -> _constructError `thenPrimIO` \ ioError ->
409 isEOF = hIsEOF stdin13
413 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
414 $True$ if no further input can be taken from {\em hdl} or for a
415 physical file, if the current I/O position is equal to the length of
416 the file. Otherwise, it returns $False$.
418 \subsubsection[Buffering]{Buffering Operations}
420 Three kinds of buffering are supported: line-buffering,
421 block-buffering or no-buffering. These modes have the following effects.
422 For output, items are written out from the internal buffer
423 according to the buffer mode:
425 \item[line-buffering] the entire output buffer is written
426 out whenever a newline is output, the output buffer overflows,
427 a flush is issued, or the handle is closed.
429 \item[block-buffering] the entire output buffer is written out whenever
430 it overflows, a flush is issued, or the handle
433 \item[no-buffering] output is written immediately, and never stored
434 in the output buffer.
437 The output buffer is emptied as soon as it has been written out.
439 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
441 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
442 the next item is obtained from the buffer;
443 otherwise, when the input buffer is empty,
444 characters up to and including the next newline
445 character are read into the buffer. No characters
446 are available until the newline character is
448 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
449 the next block of data is read into this buffer.
450 \item[no-buffering] the next input item is read and returned.
452 For most implementations, physical files will normally be block-buffered
453 and terminals will normally be line-buffered.
457 data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
459 hSetBuffering :: Handle -> BufferMode -> IO ()
461 hSetBuffering handle mode =
463 (BlockBuffering (Just n))
464 | n <= 0 -> failWith (InvalidArgument "illegal buffer size")
466 takeMVar handle >>= \ htype ->
467 if isMarked htype then
468 putMVar handle htype >>
469 failWith (UnsupportedOperation "can't set buffering for a dirty handle")
472 _ErrorHandle ioError ->
473 putMVar handle htype >>
476 putMVar handle htype >>
477 failWith (IllegalOperation "handle is closed")
478 _SemiClosedHandle _ _ ->
479 putMVar handle htype >>
480 failWith (IllegalOperation "handle is closed")
483 putMVar handle htype >>
484 failWith (IllegalOperation "buffering not supported for socket handles")
487 _ccall_ setBuffering (_filePtr other) bsize
490 putMVar handle ((hcon other) (_filePtr other) (Just mode) True)
494 putMVar handle htype >>
495 _constructError `thenPrimIO` \ ioError ->
499 isMarked :: _Handle -> Bool
500 isMarked (_ReadHandle fp m b) = b
501 isMarked (_WriteHandle fp m b) = b
502 isMarked (_AppendHandle fp m b) = b
503 isMarked (_ReadWriteHandle fp m b) = b
504 isMarked (_SocketHandle fp b) = b
510 BlockBuffering Nothing -> -2
511 BlockBuffering (Just n) -> n
513 hcon :: _Handle -> (_Addr -> (Maybe BufferMode) -> Bool -> _Handle)
514 hcon (_ReadHandle _ _ _) = _ReadHandle
515 hcon (_WriteHandle _ _ _) = _WriteHandle
516 hcon (_AppendHandle _ _ _) = _AppendHandle
517 hcon (_ReadWriteHandle _ _ _) = _ReadWriteHandle
518 hcon (_SocketHandle _ _) = \ a _ v -> _SocketHandle a v
522 Computation $hSetBuffering hdl mode$ sets the mode of buffering for
523 handle {\em hdl} on subsequent reads and writes.
527 If {\em mode} is $LineBuffering$, line-buffering should be
530 If {\em mode} is $BlockBuffering$ {\em size}, then block-buffering
531 should be enabled if possible. The size of the buffer is {\em n} items
532 if {\em size} is $Just${\em n} and is otherwise implementation-dependent.
534 If {\em mode} is $NoBuffering$, then buffering is disabled if possible.
537 If the buffer mode is changed from $BlockBuffering$ or $LineBuffering$
538 to $NoBuffering$, then any items in the output buffer are written to
539 the device, and any items in the input buffer are discarded. The
540 default buffering mode when a handle is opened is
541 implementation-dependent and may depend on the object which is
542 attached to that handle.
546 hFlush :: Handle -> IO ()
549 takeMVar handle >>= \ htype ->
551 _ErrorHandle ioError ->
552 putMVar handle htype >>
555 putMVar handle htype >>
556 failWith (IllegalOperation "handle is closed")
557 _SemiClosedHandle _ _ ->
558 putMVar handle htype >>
559 failWith (IllegalOperation "handle is closed")
561 putMVar handle htype >>
562 failWith (IllegalOperation "flush not supported for socket handles")
564 _ccall_ flushFile (_filePtr other) `thenPrimIO` \ rc ->
565 putMVar handle (_markHandle htype) >>
569 _constructError `thenPrimIO` \ ioError ->
574 Computation $flush hdl$ causes any items
575 buffered for output in handle {\em hdl} to be sent immediately to
576 the operating system.
578 \subsubsection[Seeking]{Repositioning Handles}
582 type HandlePosn = (Handle, Int)
584 hGetPosn :: Handle -> IO HandlePosn
586 takeMVar handle >>= \ htype ->
588 _ErrorHandle ioError ->
589 putMVar handle htype >>
592 putMVar handle htype >>
593 failWith (IllegalOperation "handle is closed")
594 _SemiClosedHandle _ _ ->
595 putMVar handle htype >>
596 failWith (IllegalOperation "handle is closed")
598 putMVar handle htype >>
599 failWith (IllegalOperation "position not supported for socket handles")
601 _ccall_ getFilePosn (_filePtr other) `thenPrimIO` \ posn ->
602 putMVar handle htype >>
604 return (handle, posn)
606 _constructError `thenPrimIO` \ ioError ->
609 hSetPosn :: HandlePosn -> IO ()
610 hSetPosn (handle, posn) =
611 takeMVar handle >>= \ htype ->
613 _ErrorHandle ioError ->
614 putMVar handle htype >>
617 putMVar handle htype >>
618 failWith (IllegalOperation "handle is closed")
619 _SemiClosedHandle _ _ ->
620 putMVar handle htype >>
621 failWith (IllegalOperation "handle is closed")
622 _AppendHandle _ _ _ ->
623 putMVar handle htype >>
624 failWith (IllegalOperation "handle is not seekable")
626 putMVar handle htype >>
627 failWith (IllegalOperation "seek not supported for socket handles")
629 _ccall_ setFilePosn (_filePtr other) posn `thenPrimIO` \ rc ->
630 putMVar handle (_markHandle htype) >>
634 _constructError `thenPrimIO` \ ioError ->
639 Computation $hGetPosn hdl$ returns the current I/O
640 position of {\em hdl} as an abstract position. Computation
641 $hSetPosn p$ sets the position of {\em hdl}
642 to a previously obtained position {\em p}.
646 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
648 hSeek :: Handle -> SeekMode -> Integer -> IO ()
649 hSeek handle mode offset@(J# _ s# d#) =
650 takeMVar handle >>= \ htype ->
652 _ErrorHandle ioError ->
653 putMVar handle htype >>
656 putMVar handle htype >>
657 failWith (IllegalOperation "handle is closed")
658 _SemiClosedHandle _ _ ->
659 putMVar handle htype >>
660 failWith (IllegalOperation "handle is closed")
661 _AppendHandle _ _ _ ->
662 putMVar handle htype >>
663 failWith (IllegalOperation "handle is not seekable")
665 putMVar handle htype >>
666 failWith (IllegalOperation "seek not supported for socket handles")
668 _ccall_ seekFile (_filePtr other) whence (I# s#) (_ByteArray (0,0) d#)
670 putMVar handle (_markHandle htype) >>
674 _constructError `thenPrimIO` \ ioError ->
678 whence = case mode of
679 AbsoluteSeek -> ``SEEK_SET''
680 RelativeSeek -> ``SEEK_CUR''
681 SeekFromEnd -> ``SEEK_END''
685 Computation $hSeek hdl mode i$ sets the position of handle
686 {\em hdl} depending on $mode$. If {\em mode} is
688 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
689 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
690 the current position.
691 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
693 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
694 the beginning of the file.
697 Some handles may not be seekable $hIsSeekable$, or only support a
698 subset of the possible positioning operations (e.g. it may only be
699 possible to seek to the end of a tape, or to a positive offset from
700 the beginning or current position).
702 It is not possible to set a negative I/O position, or for a physical
703 file, an I/O position beyond the current end-of-file.
705 \subsubsection[Query]{Handle Properties}
709 hIsOpen :: Handle -> IO Bool
711 takeMVar handle >>= \ htype ->
713 _ErrorHandle ioError ->
714 putMVar handle htype >>
717 putMVar handle htype >>
719 _SemiClosedHandle _ _ ->
720 putMVar handle htype >>
723 putMVar handle htype >>
726 hIsClosed :: Handle -> IO Bool
728 takeMVar handle >>= \ htype ->
730 _ErrorHandle ioError ->
731 putMVar handle htype >>
734 putMVar handle htype >>
737 putMVar handle htype >>
740 hIsReadable :: Handle -> IO Bool
742 takeMVar handle >>= \ htype ->
744 _ErrorHandle ioError ->
745 putMVar handle htype >>
748 putMVar handle htype >>
749 failWith (IllegalOperation "handle is closed")
750 _SemiClosedHandle _ _ ->
751 putMVar handle htype >>
752 failWith (IllegalOperation "handle is closed")
754 putMVar handle htype >>
755 return (isReadable other)
757 isReadable (_ReadHandle _ _ _) = True
758 isReadable (_ReadWriteHandle _ _ _) = True
759 isReadable (_SocketHandle _ _) = True
762 hIsWritable :: Handle -> IO Bool
764 takeMVar handle >>= \ htype ->
766 _ErrorHandle ioError ->
767 putMVar handle htype >>
770 putMVar handle htype >>
771 failWith (IllegalOperation "handle is closed")
772 _SemiClosedHandle _ _ ->
773 putMVar handle htype >>
774 failWith (IllegalOperation "handle is closed")
776 putMVar handle htype >>
777 return (isWritable other)
779 isWritable (_AppendHandle _ _ _) = True
780 isWritable (_WriteHandle _ _ _) = True
781 isWritable (_ReadWriteHandle _ _ _) = True
784 _getBufferMode :: _Handle -> PrimIO _Handle
785 _getBufferMode htype =
786 case _bufferMode htype of
787 Just x -> returnPrimIO htype
789 _ccall_ getBufferMode (_filePtr htype) `thenPrimIO` \ rc ->
793 0 -> Just NoBuffering
794 -1 -> Just LineBuffering
795 -2 -> Just (BlockBuffering Nothing)
797 n -> Just (BlockBuffering (Just n))
799 returnPrimIO (case htype of
800 _ReadHandle fp _ b -> _ReadHandle fp mode b
801 _WriteHandle fp _ b -> _WriteHandle fp mode b
802 _AppendHandle fp _ b -> _AppendHandle fp mode b
803 _ReadWriteHandle fp _ b -> _ReadWriteHandle fp mode b)
805 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
806 hIsBlockBuffered handle =
807 takeMVar handle >>= \ htype ->
809 _ErrorHandle ioError ->
810 putMVar handle htype >>
813 putMVar handle htype >>
814 failWith (IllegalOperation "handle is closed")
815 _SemiClosedHandle _ _ ->
816 putMVar handle htype >>
817 failWith (IllegalOperation "handle is closed")
819 _getBufferMode other `thenPrimIO` \ other ->
820 case _bufferMode other of
821 Just (BlockBuffering size) ->
822 putMVar handle other >>
825 putMVar handle other >>
826 return (False, Nothing)
828 _constructError `thenPrimIO` \ ioError ->
831 hIsLineBuffered :: Handle -> IO Bool
832 hIsLineBuffered handle =
833 takeMVar handle >>= \ htype ->
835 _ErrorHandle ioError ->
836 putMVar handle htype >>
839 putMVar handle htype >>
840 failWith (IllegalOperation "handle is closed")
841 _SemiClosedHandle _ _ ->
842 putMVar handle htype >>
843 failWith (IllegalOperation "handle is closed")
845 _getBufferMode other `thenPrimIO` \ other ->
846 case _bufferMode other of
847 Just LineBuffering ->
848 putMVar handle other >>
851 putMVar handle other >>
854 _constructError `thenPrimIO` \ ioError ->
857 hIsNotBuffered :: Handle -> IO Bool
858 hIsNotBuffered handle =
859 takeMVar handle >>= \ htype ->
861 _ErrorHandle ioError ->
862 putMVar handle htype >>
865 putMVar handle htype >>
866 failWith (IllegalOperation "handle is closed")
867 _SemiClosedHandle _ _ ->
868 putMVar handle htype >>
869 failWith (IllegalOperation "handle is closed")
871 _getBufferMode other `thenPrimIO` \ other ->
872 case _bufferMode other of
874 putMVar handle other >>
877 putMVar handle other >>
880 _constructError `thenPrimIO` \ ioError ->
883 hIsSeekable :: Handle -> IO Bool
885 takeMVar handle >>= \ htype ->
887 _ErrorHandle ioError ->
888 putMVar handle htype >>
891 putMVar handle htype >>
892 failWith (IllegalOperation "handle is closed")
893 _SemiClosedHandle _ _ ->
894 putMVar handle htype >>
895 failWith (IllegalOperation "handle is closed")
896 _AppendHandle _ _ _ ->
897 putMVar handle htype >>
900 putMVar handle htype >>
903 _ccall_ seekFileP (_filePtr other) `thenPrimIO` \ rc ->
904 putMVar handle htype >>
908 _ -> _constructError `thenPrimIO` \ ioError ->
914 A number of operations return information about the properties of a
915 handle. Each of these operations returns $True$ if the
916 handle has the specified property, and $False$
919 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
920 {\em hdl} is not block-buffered. Otherwise it returns
921 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
922 $( Just n )$ for block-buffering of {\em n} bytes.