[project @ 1996-01-18 16:33:17 by partain]
[ghc-hetmet.git] / ghc / lib / prelude / PreludeStdIO.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
3 %
4 \section[PrelStdIO]{Haskell 1.3 Standard I/O}
5
6 This module defines Haskell {\em handles} and the operations which are
7 supported for them.
8
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.
17
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
21 of that file.
22
23 \subsection[Handles]{Handles}
24
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.
29
30 A handle has at least the following properties:
31 \begin{itemize}
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).
39 \end{itemize}
40
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
46 remain to it.
47
48 \subsubsection[SemiClosed]{Semi-Closed Handles}
49
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$.
55
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
58 becomes closed:
59 \begin{itemize}
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.
64 \end{itemize}
65
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.
70
71 \begin{code}
72 module PreludeStdIO (
73     _Handle(..),
74     Handle(..), 
75     FilePath(..), 
76     IOMode(..),
77     BufferMode(..),
78     HandlePosn(..),
79     SeekMode(..),
80     stdin13,
81     stdout13,
82     stderr13,
83     openFile,
84     hClose,
85     hFileSize,
86     hIsEOF,
87     isEOF,
88     hSetBuffering,
89     hFlush,
90     hGetPosn,
91     hSetPosn,
92     hSeek,
93     hIsBlockBuffered,
94     hIsLineBuffered,
95     hIsNotBuffered,
96     hIsOpen,
97     hIsClosed,
98     hIsReadable,
99     hIsWritable,
100     hIsSeekable,
101     _filePtr,
102     _bufferMode,
103     _getBufferMode,
104     _markHandle,
105     Maybe(..)
106   ) where
107
108 import Cls
109 import Core
110 import IChar
111 import IInt
112 import IList
113 import List             ( (++) )
114 import PS               ( _PackedString, _unpackPS )
115 import Prel             ( otherwise, not, (.) )
116 import Text
117 import TyArray          -- instance _CCallable (_ByteArray a)
118 import TyComplex
119
120 import PreludeIOError
121 import PreludeMonadicIO
122 import PreludePrimIO
123 import PreludeGlaST
124
125 ---------------------------------
126 infixr 1 `my_then`
127
128 my_then :: IO a -> (a -> PrimIO b) -> PrimIO b
129 {-# INLINE my_then   #-}
130
131 my_then m k = m `thenPrimIO` \ r -> k' r
132   where
133     k' (Right x)  = k x
134     k' (Left err) = error "my_then"
135 ---------------------------------
136
137 data Maybe a = Nothing | Just a {-partain-}deriving (Eq, Ord, Text)
138
139 data _Handle = _ErrorHandle IOError13
140              | _ClosedHandle
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     
147
148 type Handle = _MVar _Handle
149 type FilePath = String
150
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
158
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)
165
166 _markHandle :: _Handle -> _Handle
167 _markHandle h@(_ReadHandle fp m b)
168   | b = h
169   | otherwise = _ReadHandle fp m True
170 _markHandle h@(_WriteHandle fp m b)
171   | b = h
172   | otherwise = _WriteHandle fp m True
173 _markHandle h@(_AppendHandle fp m b)
174   | b = h
175   | otherwise = _AppendHandle fp m True
176 _markHandle h@(_ReadWriteHandle fp m b)
177   | b = h
178   | otherwise = _ReadWriteHandle fp m True
179 _markHandle h@(_SocketHandle fp b)
180   | b = h
181   | otherwise = _SocketHandle fp True
182
183 \end{code}
184
185 \subsubsection[StandardHandles]{Standard Handles}
186
187 \begin{code}
188
189 stdin13, stdout13, stderr13 :: Handle
190
191 stdin13 = unsafePerformPrimIO (
192     newEmptyMVar                                        `my_then` \ handle ->
193     _ccall_ getLock (``stdin''::_Addr) 0                `thenPrimIO` \ rc ->
194     (case rc of
195        0 -> putMVar handle _ClosedHandle
196        1 -> putMVar handle (_ReadHandle ``stdin'' Nothing False)
197        _ -> _constructError                             `thenPrimIO` \ ioError -> 
198             putMVar handle (_ErrorHandle ioError)
199     )                                                   `seqPrimIO`
200     returnPrimIO handle
201   )
202
203 stdout13 = unsafePerformPrimIO (
204     newEmptyMVar                                        `my_then` \ handle ->
205     _ccall_ getLock (``stdout''::_Addr) 1               `thenPrimIO` \ rc ->
206     (case rc of
207        0 -> putMVar handle _ClosedHandle
208        1 -> putMVar handle (_WriteHandle ``stdout'' Nothing False)
209        _ -> _constructError                             `thenPrimIO` \ ioError -> 
210             putMVar handle (_ErrorHandle ioError)
211     )                                                   `seqPrimIO`
212     returnPrimIO handle
213   )
214
215 stderr13 = unsafePerformPrimIO (
216     newEmptyMVar                                        `my_then` \ handle ->
217     _ccall_ getLock (``stderr''::_Addr) 1               `thenPrimIO` \ rc ->
218     (case rc of
219        0 -> putMVar handle _ClosedHandle
220        1 -> putMVar handle (_WriteHandle ``stderr'' (Just NoBuffering) False)   
221        _ -> _constructError                             `thenPrimIO` \ ioError -> 
222             putMVar handle (_ErrorHandle ioError)
223     )                                                   `seqPrimIO`
224     returnPrimIO handle
225   )
226
227 \end{code}
228
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.
233
234 \subsubsection[OpeningClosing]{Opening and Closing Files}
235
236 \begin{code}
237
238 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
239
240 openFile :: FilePath -> IOMode -> IO Handle
241
242 openFile f m = 
243     _ccall_ openFile f m'                           `thenPrimIO` \ ptr ->
244     if ptr /= ``NULL'' then
245         newEmptyMVar                                >>= \ handle ->
246         putMVar handle (htype ptr Nothing False)    >>
247         return handle
248     else
249         _constructError                             `thenPrimIO` \ ioError -> 
250         let
251             improved_error -- a HACK, I guess
252               = case ioError of
253                   AlreadyExists    msg -> AlreadyExists    (msg ++ ": " ++ f)
254                   NoSuchThing      msg -> NoSuchThing      (msg ++ ": " ++ f)
255                   PermissionDenied msg -> PermissionDenied (msg ++ ": " ++ f)
256                   _                    -> ioError
257         in
258         failWith improved_error
259   where
260     m' = case m of 
261            ReadMode      -> "r"
262            WriteMode     -> "w"
263            AppendMode    -> "a"
264            ReadWriteMode -> "r+"
265     htype = case m of 
266               ReadMode      -> _ReadHandle
267               WriteMode     -> _WriteHandle
268               AppendMode    -> _AppendHandle
269               ReadWriteMode -> _ReadWriteHandle
270
271 \end{code}
272
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$.
277
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).
284
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.
293
294 Two files are the same if they have the same absolute name.  An
295 implementation is free to impose stricter conditions.
296
297 \begin{code}
298
299 hClose :: Handle -> IO ()
300
301 hClose handle =
302     takeMVar handle                                 >>= \ htype ->
303     putMVar handle _ClosedHandle                    >>
304     case htype of 
305       _ErrorHandle ioError ->
306           failWith ioError
307       _ClosedHandle -> 
308           failWith (IllegalOperation "handle is closed")
309       _SemiClosedHandle fp (buf,_) ->
310           (if buf /= ``NULL'' then
311               _ccall_ free buf
312            else                     
313               returnPrimIO ())                      `thenPrimIO` \ () ->
314           if fp /= ``NULL'' then
315               _ccall_ closeFile fp                  `thenPrimIO` \ rc ->
316               if rc == 0 then 
317                   return ()
318               else
319                   _constructError                   `thenPrimIO` \ ioError ->
320                   failWith ioError
321           else                      
322               return ()
323       other -> 
324           _ccall_ closeFile (_filePtr other)        `thenPrimIO` \ rc ->
325           if rc == 0 then 
326               return ()
327           else
328               _constructError                       `thenPrimIO` \ ioError ->
329               failWith ioError
330 \end{code}
331
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$.
335
336 \subsubsection[EOF]{Detecting the End of Input}
337
338 \begin{code}
339
340 hFileSize :: Handle -> IO Integer
341
342 hFileSize handle =
343     takeMVar handle                                 >>= \ htype ->
344     case htype of 
345       _ErrorHandle ioError ->
346           putMVar handle htype                      >>
347           failWith ioError
348       _ClosedHandle -> 
349           putMVar handle htype                      >>
350           failWith (IllegalOperation "handle is closed")
351       _SemiClosedHandle _ _ -> 
352           putMVar handle htype                      >>
353           failWith (IllegalOperation "handle is closed")
354       _SocketHandle _ _ ->
355           putMVar handle htype                      >>
356           failWith (IllegalOperation "socket handles have no size")
357       other ->
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#)
364                                                     `thenPrimIO` \ rc ->
365                putMVar handle htype                 `seqPrimIO`
366                if rc == 0 then
367                    return result
368                else
369                     _constructError                 `thenPrimIO` \ ioError ->
370                     failWith ioError
371
372 \end{code}
373
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}.
377
378 \begin{code}
379
380 hIsEOF :: Handle -> IO Bool
381 hIsEOF handle =
382     takeMVar handle                                 >>= \ htype ->
383     case htype of 
384       _ErrorHandle ioError ->
385           putMVar handle htype                      >>
386           failWith ioError
387       _ClosedHandle -> 
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")
399       other -> 
400           _ccall_ fileEOF (_filePtr other)          `thenPrimIO` \ rc ->
401           putMVar handle (_markHandle htype)        >>
402           case rc of
403             0 -> return False
404             1 -> return True
405             _ -> _constructError                    `thenPrimIO` \ ioError ->
406                  failWith ioError
407
408 isEOF :: IO Bool
409 isEOF = hIsEOF stdin13
410
411 \end{code}
412
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$.
417
418 \subsubsection[Buffering]{Buffering Operations}
419
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:
424 \begin{itemize}
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.
428
429 \item[block-buffering] the entire output buffer is written out whenever 
430 it overflows, a flush is issued, or the handle
431 is closed.
432
433 \item[no-buffering] output is written immediately, and never stored
434 in the output buffer.
435 \end{itemize}
436
437 The output buffer is emptied as soon as it has been written out.
438
439 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
440 \begin{itemize}
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
447 available.
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.
451 \end{itemize}
452 For most implementations, physical files will normally be block-buffered 
453 and terminals will normally be line-buffered.
454
455 \begin{code}
456
457 data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
458
459 hSetBuffering :: Handle -> BufferMode -> IO ()
460
461 hSetBuffering handle mode =
462     case mode of
463       (BlockBuffering (Just n)) 
464         | n <= 0 -> failWith (InvalidArgument "illegal buffer size")
465       other ->
466           takeMVar handle                           >>= \ htype ->
467           if isMarked htype then
468               putMVar handle htype                  >>
469               failWith (UnsupportedOperation "can't set buffering for a dirty handle")
470           else
471               case htype of
472                 _ErrorHandle ioError ->
473                     putMVar handle htype                    >>
474                     failWith ioError
475                 _ClosedHandle ->
476                     putMVar handle htype                    >>
477                     failWith (IllegalOperation "handle is closed")
478                 _SemiClosedHandle _ _ ->
479                     putMVar handle htype                    >>
480                     failWith (IllegalOperation "handle is closed")
481 {-
482                 _SocketHandle _ _ ->
483                     putMVar handle htype                    >>
484                     failWith (IllegalOperation "buffering not supported for socket handles")
485 -}
486                 other ->
487                     _ccall_ setBuffering (_filePtr other) bsize
488                                                             `thenPrimIO` \ rc -> 
489                     if rc == 0 then
490                         putMVar handle ((hcon other) (_filePtr other) (Just mode) True)
491                                                             >>
492                         return ()
493                     else
494                         putMVar handle htype                >>
495                         _constructError                     `thenPrimIO` \ ioError ->
496                         failWith ioError
497                 
498   where
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
505
506     bsize :: Int
507     bsize = case mode of
508               NoBuffering -> 0
509               LineBuffering -> -1
510               BlockBuffering Nothing -> -2
511               BlockBuffering (Just n) -> n
512
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
519
520 \end{code}
521
522 Computation $hSetBuffering hdl mode$ sets the mode of buffering for
523 handle {\em hdl} on subsequent reads and writes.
524
525 \begin{itemize}
526 \item
527 If {\em mode} is $LineBuffering$, line-buffering should be
528 enabled if possible.
529 \item
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.
533 \item
534 If {\em mode} is $NoBuffering$, then buffering is disabled if possible.
535 \end{itemize}
536
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.
543
544 \begin{code}
545
546 hFlush :: Handle -> IO () 
547
548 hFlush handle = 
549     takeMVar handle                                 >>= \ htype ->
550     case htype of 
551       _ErrorHandle ioError ->
552           putMVar handle htype                      >>
553           failWith ioError
554       _ClosedHandle ->
555           putMVar handle htype                      >>
556           failWith (IllegalOperation "handle is closed")
557       _SemiClosedHandle _ _ ->
558           putMVar handle htype                      >>
559           failWith (IllegalOperation "handle is closed")
560       _SocketHandle _ _ ->
561           putMVar handle htype                      >>
562           failWith (IllegalOperation "flush not supported for socket handles")
563       other ->
564           _ccall_ flushFile (_filePtr other)        `thenPrimIO` \ rc ->
565           putMVar handle (_markHandle htype)        >>
566                if rc == 0 then 
567                    return ()
568                else
569                     _constructError                 `thenPrimIO` \ ioError ->
570                     failWith ioError
571
572 \end{code}
573
574 Computation $flush hdl$ causes any items
575 buffered for output in handle {\em hdl} to be sent immediately to
576 the operating system.
577
578 \subsubsection[Seeking]{Repositioning Handles}
579
580 \begin{code}
581
582 type HandlePosn = (Handle, Int)
583
584 hGetPosn :: Handle -> IO HandlePosn
585 hGetPosn handle = 
586     takeMVar handle                                 >>= \ htype ->
587     case htype of 
588       _ErrorHandle ioError ->
589           putMVar handle htype                      >>
590           failWith ioError
591       _ClosedHandle ->
592           putMVar handle htype                      >>
593           failWith (IllegalOperation "handle is closed")
594       _SemiClosedHandle _ _ ->
595           putMVar handle htype                      >>
596           failWith (IllegalOperation "handle is closed")
597       _SocketHandle _ _ ->
598           putMVar handle htype                      >>
599           failWith (IllegalOperation "position not supported for socket handles")
600       other -> 
601           _ccall_ getFilePosn (_filePtr other)      `thenPrimIO` \ posn ->
602           putMVar handle htype                      >>
603           if posn /= -1 then
604               return (handle, posn)
605           else
606               _constructError                       `thenPrimIO` \ ioError ->
607               failWith ioError
608
609 hSetPosn :: HandlePosn -> IO () 
610 hSetPosn (handle, posn) = 
611     takeMVar handle                                 >>= \ htype ->
612     case htype of 
613       _ErrorHandle ioError ->
614           putMVar handle htype                      >>
615           failWith ioError
616       _ClosedHandle ->
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")
625       _SocketHandle _ _ ->
626           putMVar handle htype                      >>
627           failWith (IllegalOperation "seek not supported for socket handles")
628       other -> 
629           _ccall_ setFilePosn (_filePtr other) posn `thenPrimIO` \ rc ->
630           putMVar handle (_markHandle htype)        >>
631                if rc == 0 then 
632                    return ()
633                else
634                    _constructError                  `thenPrimIO` \ ioError ->
635                    failWith ioError
636
637 \end{code}
638
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}.
643
644 \begin{code}
645
646 data SeekMode =  AbsoluteSeek | RelativeSeek | SeekFromEnd
647
648 hSeek :: Handle -> SeekMode -> Integer -> IO () 
649 hSeek handle mode offset@(J# _ s# d#) = 
650     takeMVar handle                                 >>= \ htype ->
651     case htype of 
652       _ErrorHandle ioError ->
653           putMVar handle htype                      >>
654           failWith ioError
655       _ClosedHandle ->
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")
664       _SocketHandle _ _ ->
665           putMVar handle htype                      >>
666           failWith (IllegalOperation "seek not supported for socket handles")
667       other -> 
668           _ccall_ seekFile (_filePtr other) whence (I# s#) (_ByteArray (0,0) d#)
669                                                     `thenPrimIO` \ rc ->
670           putMVar handle (_markHandle htype)        >>
671                if rc == 0 then 
672                    return ()
673                else
674                     _constructError                 `thenPrimIO` \ ioError ->
675                     failWith ioError
676   where
677     whence :: Int
678     whence = case mode of
679                AbsoluteSeek -> ``SEEK_SET''
680                RelativeSeek -> ``SEEK_CUR''
681                SeekFromEnd -> ``SEEK_END''
682
683 \end{code}
684
685 Computation $hSeek hdl mode i$ sets the position of handle
686 {\em hdl} depending on $mode$.  If {\em mode} is
687 \begin{itemize}
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
692 the end of the file.
693 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
694 the beginning of the file.
695 \end{itemize}
696
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).
701
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. 
704
705 \subsubsection[Query]{Handle Properties}
706
707 \begin{code}
708
709 hIsOpen :: Handle -> IO Bool
710 hIsOpen handle = 
711     takeMVar handle                                 >>= \ htype ->
712     case htype of 
713       _ErrorHandle ioError ->
714           putMVar handle htype                      >>
715           failWith ioError
716       _ClosedHandle ->
717           putMVar handle htype                      >>
718           return False
719       _SemiClosedHandle _ _ ->
720           putMVar handle htype                      >>
721           return False
722       other ->
723           putMVar handle htype                      >>
724           return True
725
726 hIsClosed :: Handle -> IO Bool
727 hIsClosed handle = 
728     takeMVar handle                                 >>= \ htype ->
729     case htype of 
730       _ErrorHandle ioError ->
731           putMVar handle htype                      >>
732           failWith ioError
733       _ClosedHandle ->
734           putMVar handle htype                      >>
735           return True
736       other ->
737           putMVar handle htype                      >>
738           return False
739
740 hIsReadable :: Handle -> IO Bool
741 hIsReadable handle = 
742     takeMVar handle                                 >>= \ htype ->
743     case htype of 
744       _ErrorHandle ioError ->
745           putMVar handle htype                      >>
746           failWith ioError
747       _ClosedHandle ->
748           putMVar handle htype                      >>
749           failWith (IllegalOperation "handle is closed")
750       _SemiClosedHandle _ _ ->
751           putMVar handle htype                      >>
752           failWith (IllegalOperation "handle is closed")
753       other ->
754           putMVar handle htype                      >>
755           return (isReadable other)
756   where
757     isReadable (_ReadHandle _ _ _) = True
758     isReadable (_ReadWriteHandle _ _ _) = True
759     isReadable (_SocketHandle _ _) = True
760     isReadable _ = False
761
762 hIsWritable :: Handle -> IO Bool
763 hIsWritable handle = 
764     takeMVar handle                                 >>= \ htype ->
765     case htype of 
766       _ErrorHandle ioError ->
767           putMVar handle htype                      >>
768           failWith ioError
769       _ClosedHandle ->
770           putMVar handle htype                      >>
771           failWith (IllegalOperation "handle is closed")
772       _SemiClosedHandle _ _ ->
773           putMVar handle htype                      >>
774           failWith (IllegalOperation "handle is closed")
775       other ->
776           putMVar handle htype                      >>
777           return (isWritable other)
778   where
779     isWritable (_AppendHandle _ _ _) = True
780     isWritable (_WriteHandle _ _ _) = True
781     isWritable (_ReadWriteHandle _ _ _) = True
782     isWritable _ = False
783
784 _getBufferMode :: _Handle -> PrimIO _Handle
785 _getBufferMode htype =
786     case _bufferMode htype of
787       Just x -> returnPrimIO htype
788       Nothing ->
789         _ccall_ getBufferMode (_filePtr htype)      `thenPrimIO` \ rc ->
790         let 
791             mode = 
792                 case rc of
793                   0  -> Just NoBuffering
794                   -1 -> Just LineBuffering
795                   -2 -> Just (BlockBuffering Nothing)
796                   -3 -> Nothing
797                   n  -> Just (BlockBuffering (Just n))
798         in
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)
804
805 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
806 hIsBlockBuffered handle =
807     takeMVar handle                                 >>= \ htype ->
808     case htype of 
809       _ErrorHandle ioError ->
810           putMVar handle htype                      >>
811           failWith ioError
812       _ClosedHandle ->
813           putMVar handle htype                      >>
814           failWith (IllegalOperation "handle is closed")
815       _SemiClosedHandle _ _ ->
816           putMVar handle htype                      >>
817           failWith (IllegalOperation "handle is closed")
818       other ->
819           _getBufferMode other                      `thenPrimIO` \ other ->
820           case _bufferMode other of
821             Just (BlockBuffering size) ->
822                 putMVar handle other                >>
823                 return (True, size)
824             Just _ ->
825                 putMVar handle other                >>
826                 return (False, Nothing)
827             Nothing -> 
828                 _constructError                     `thenPrimIO` \ ioError ->
829                 failWith ioError
830
831 hIsLineBuffered :: Handle -> IO Bool
832 hIsLineBuffered handle =
833     takeMVar handle                                 >>= \ htype ->
834     case htype of 
835       _ErrorHandle ioError ->
836           putMVar handle htype                      >>
837           failWith ioError
838       _ClosedHandle ->
839           putMVar handle htype                      >>
840           failWith (IllegalOperation "handle is closed")
841       _SemiClosedHandle _ _ ->
842           putMVar handle htype                      >>
843           failWith (IllegalOperation "handle is closed")
844       other ->
845           _getBufferMode other                      `thenPrimIO` \ other ->
846           case _bufferMode other of
847             Just LineBuffering ->
848                 putMVar handle other                >>
849                 return True
850             Just _ ->
851                 putMVar handle other                >>
852                 return False
853             Nothing -> 
854                 _constructError                     `thenPrimIO` \ ioError ->
855                 failWith ioError
856
857 hIsNotBuffered :: Handle -> IO Bool
858 hIsNotBuffered handle =
859     takeMVar handle                                 >>= \ htype ->
860     case htype of 
861       _ErrorHandle ioError ->
862           putMVar handle htype                      >>
863           failWith ioError
864       _ClosedHandle ->
865           putMVar handle htype                      >>
866           failWith (IllegalOperation "handle is closed")
867       _SemiClosedHandle _ _ ->
868           putMVar handle htype                      >>
869           failWith (IllegalOperation "handle is closed")
870       other ->
871           _getBufferMode other                      `thenPrimIO` \ other ->
872           case _bufferMode other of
873             Just NoBuffering ->
874                 putMVar handle other                >>
875                 return True
876             Just _ ->
877                 putMVar handle other                >>
878                 return False
879             Nothing -> 
880                 _constructError                     `thenPrimIO` \ ioError ->
881                 failWith ioError
882
883 hIsSeekable :: Handle -> IO Bool
884 hIsSeekable handle = 
885     takeMVar handle                                 >>= \ htype ->
886     case htype of 
887       _ErrorHandle ioError ->
888           putMVar handle htype                      >>
889           failWith ioError
890       _ClosedHandle ->
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                      >>
898           return False
899       _SocketHandle _ _ ->
900           putMVar handle htype                      >>
901           return False
902       other ->
903           _ccall_ seekFileP (_filePtr other)        `thenPrimIO` \ rc ->
904           putMVar handle htype                      >>
905           case rc of
906             0 -> return False
907             1 -> return True
908             _ -> _constructError                    `thenPrimIO` \ ioError ->
909                  failWith ioError
910
911
912 \end{code}
913
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$
917 otherwise.
918
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.
923