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