caa8c50886f89d89e5c3bbf5836f0e86f1d91f9e
[ghc-hetmet.git] / ghc / lib / std / PrelHandle.lhs
1
2 % (c) The AQUA Project, Glasgow University, 1994-1996
3 %
4
5 \section[PrelHandle]{Module @PrelHandle@}
6
7 This module defines Haskell {\em handles} and the basic operations
8 which are supported for them.
9
10 \begin{code}
11 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
12 #include "cbits/error.h"
13
14 #ifndef __HUGS__ /* Hugs just includes this in PreludeBuiltin so no header needed */
15 module PrelHandle where
16
17 import PrelBase
18 import PrelArr          ( newVar, readVar, writeVar, ByteArray )
19 import PrelRead         ( Read )
20 import PrelList         ( span )
21 import PrelIOBase
22 import PrelException    ( throw, ioError, catchException )
23 import PrelMaybe        ( Maybe(..) )
24 import PrelAddr         ( Addr, nullAddr )
25 import PrelBounded      ()   -- get at Bounded Int instance.
26 import PrelNum          ( toInteger )
27 import PrelWeak         ( addForeignFinaliser )
28 #if __CONCURRENT_HASKELL__
29 import PrelConc
30 #endif
31 import Ix
32
33 #ifndef __PARALLEL_HASKELL__
34 import PrelForeign  ( makeForeignObj )
35 #endif
36
37 #endif /* ndef(__HUGS__) */
38
39 #ifdef __HUGS__
40 #define cat2(x,y)  x/**/y
41 #define CCALL(fun) cat2(prim_,fun)
42 #define __CONCURRENT_HASKELL__
43 #define stToIO id
44 #define sizeof_int64 8
45 #else
46 #define CCALL(fun) _ccall_ fun
47 #define const_BUFSIZ ``BUFSIZ''
48 #define primPackString
49 #endif
50
51 #ifndef __PARALLEL_HASKELL__
52 #define FILE_OBJECT         ForeignObj
53 #else
54 #define FILE_OBJECT         Addr
55 #endif
56
57 \end{code}
58
59 %*********************************************************
60 %*                                                      *
61 \subsection{Types @Handle@, @Handle__@}
62 %*                                                      *
63 %*********************************************************
64
65 The @Handle@ and @Handle__@ types are defined in @IOBase@.
66
67 \begin{code}
68 {-# INLINE newHandle   #-}
69 {-# INLINE withHandle #-}
70 {-# INLINE writeHandle #-}
71 newHandle     :: Handle__ -> IO Handle
72 withHandle    :: Handle   -> (Handle__ -> IO a) -> IO a
73 writeHandle   :: Handle -> Handle__ -> IO ()
74
75 #if defined(__CONCURRENT_HASKELL__)
76
77 -- Use MVars for concurrent Haskell
78 newHandle hc  = newMVar hc      >>= \ h ->
79                 return (Handle h)
80
81   -- withHandle grabs the handle lock, performs
82   -- some operation over it, making sure that we
83   -- unlock & reset the handle state should an
84   -- exception occur while performing said op.
85 withHandle (Handle h) act = do
86    h_ <- takeMVar h
87    v  <- catchException (act h_) (\ ex -> putMVar h h_ >> throw ex)
88    return v
89    
90 writeHandle (Handle h) hc = putMVar h hc
91 #else 
92
93 -- Use ordinary MutableVars for non-concurrent Haskell
94 newHandle hc  = stToIO (newVar  hc      >>= \ h ->
95                         return (Handle h))
96
97    -- of questionable value to install this exception
98    -- handler, but let's do it in the non-concurrent
99    -- case too, for now.
100 withHandle (Handle h) act = do
101    h_ <- stToIO (readVar h)
102    v  <- catchException (act h_) (\ ex -> stToIO (writeVar h h_) >> throw ex)
103    return v
104
105 writeHandle (Handle h) hc = stToIO (writeVar h hc)
106 #endif
107
108 \end{code}
109
110 nullFile__ is only used for closed handles, plugging it in as a null
111 file object reference.
112
113 \begin{code}
114 nullFile__ :: FILE_OBJECT
115 nullFile__ = 
116 #ifndef __PARALLEL_HASKELL__
117     unsafePerformIO (makeForeignObj nullAddr)
118 #else
119     nullAddr
120 #endif
121
122
123 mkClosedHandle__ :: Handle__
124 mkClosedHandle__ = 
125   Handle__ 
126            nullFile__
127            ClosedHandle 
128            NoBuffering
129            "closed file"
130
131 mkErrorHandle__ :: IOError -> Handle__
132 mkErrorHandle__ ioe =
133   Handle__
134            nullFile__ 
135            (ErrorHandle ioe)
136            NoBuffering
137            "error handle"
138 \end{code}
139
140 %*********************************************************
141 %*                                                      *
142 \subsection{Handle Finalisers}
143 %*                                                      *
144 %*********************************************************
145
146 \begin{code}
147 #ifndef __HUGS__
148 freeStdFileObject :: ForeignObj -> IO ()
149 freeStdFileObject fo = CCALL(freeStdFileObject) fo
150
151 freeFileObject :: ForeignObj -> IO ()
152 freeFileObject fo = CCALL(freeFileObject) fo
153 #else
154 foreign import stdcall "libHS_cbits.so" "freeStdFileObject" freeStdFileObject :: ForeignObj -> IO ()
155 foreign import stdcall "libHS_cbits.so" "freeFileObject" freeFileObject :: ForeignObj -> IO ()
156 #endif
157 \end{code}
158
159 %*********************************************************
160 %*                                                      *
161 \subsection[StdHandles]{Standard handles}
162 %*                                                      *
163 %*********************************************************
164
165 Three handles are allocated during program initialisation.  The first
166 two manage input or output from the Haskell program's standard input
167 or output channel respectively.  The third manages output to the
168 standard error channel. These handles are initially open.
169
170
171 \begin{code}
172 stdin, stdout, stderr :: Handle
173
174 stdout = unsafePerformIO (do
175     rc <- CCALL(getLock) (1::Int) (1::Int)   -- ConcHask: SAFE, won't block
176     case (rc::Int) of
177        0 -> newHandle (mkClosedHandle__)
178        1 -> do
179 #ifndef __CONCURRENT_HASKELL__
180             fo <- CCALL(openStdFile) (1::Int) 
181                                      (1::Int){-flush on close-}
182                                      (0::Int){-writeable-}  -- ConcHask: SAFE, won't block
183 #else
184             fo <- CCALL(openStdFile) (1::Int)
185                                      ((1{-flush on close-} {-+ 128 don't block on I/O-})::Int)
186                                      (0::Int){-writeable-}  -- ConcHask: SAFE, won't block
187 #endif
188                                             -- NOTE: turn off non-blocking I/O until 
189                                             -- we've got proper support for threadWait{Read,Write}
190
191 #ifndef __PARALLEL_HASKELL__
192             fo <- makeForeignObj fo
193             addForeignFinaliser fo (freeStdFileObject fo)
194 #endif
195
196 #ifdef __HUGS__
197 /* I dont care what the Haskell report says, in an interactive system,
198  * stdout should be unbuffered by default.
199  */
200             let bm = NoBuffering
201 #else
202             (bm, bf_size)  <- getBMode__ fo
203             mkBuffer__ fo bf_size
204 #endif
205             newHandle (Handle__ fo WriteHandle bm "stdout")
206        _ -> do ioError <- constructError "stdout"
207                newHandle (mkErrorHandle__ ioError)
208   )
209
210 stdin = unsafePerformIO (do
211     rc <- CCALL(getLock) (0::Int) (0::Int)   -- ConcHask: SAFE, won't block
212     case (rc::Int) of
213        0 -> newHandle (mkClosedHandle__)
214        1 -> do
215 #ifndef __CONCURRENT_HASKELL__
216             fo <- CCALL(openStdFile) (0::Int)
217                                      (0::Int){-don't flush on close -}
218                                      (1::Int){-readable-}  -- ConcHask: SAFE, won't block
219 #else
220             fo <- CCALL(openStdFile) (0::Int)
221                                      ((0{-flush on close-} {-+ 128 don't block on I/O-})::Int)
222                                      (1::Int){-readable-}  -- ConcHask: SAFE, won't block
223 #endif
224
225 #ifndef __PARALLEL_HASKELL__
226             fo <- makeForeignObj fo
227             addForeignFinaliser fo (freeStdFileObject fo)
228 #endif
229             (bm, bf_size) <- getBMode__ fo
230             mkBuffer__ fo bf_size
231             hdl <- newHandle (Handle__ fo ReadHandle bm "stdin")
232              -- when stdin and stdout are both connected to a terminal, ensure
233              -- that anything buffered on stdout is flushed prior to reading from stdin.
234              -- 
235             hConnectTerms stdout hdl
236             return hdl
237        _ -> do ioError <- constructError "stdin"
238                newHandle (mkErrorHandle__ ioError)
239   )
240
241
242 stderr = unsafePerformIO (do
243     rc <- CCALL(getLock) (2::Int) (1::Int){-writeable-}  -- ConcHask: SAFE, won't block
244     case (rc::Int) of
245        0 -> newHandle (mkClosedHandle__)
246        1 -> do
247 #ifndef __CONCURRENT_HASKELL__
248             fo <- CCALL(openStdFile) (2::Int)
249                                      (1::Int){-flush on close-}
250                                      (0::Int){-writeable-} -- ConcHask: SAFE, won't block
251 #else
252             fo <- CCALL(openStdFile) (2::Int)
253                                      ((1{-flush on close-} {- + 128 don't block on I/O-})::Int)
254                                      (0::Int){-writeable-} -- ConcHask: SAFE, won't block
255 #endif
256
257 #ifndef __PARALLEL_HASKELL__
258             fo <- makeForeignObj fo
259             addForeignFinaliser fo (freeStdFileObject fo)
260 #endif
261             hdl <- newHandle (Handle__ fo WriteHandle NoBuffering "stderr")
262             -- when stderr and stdout are both connected to a terminal, ensure
263             -- that anything buffered on stdout is flushed prior to writing to
264             -- stderr.
265             hConnectTo stdout hdl
266             return hdl
267
268        _ -> do ioError <- constructError "stderr"
269                newHandle (mkErrorHandle__ ioError)
270   )
271 \end{code}
272
273 %*********************************************************
274 %*                                                      *
275 \subsection[OpeningClosing]{Opening and Closing Files}
276 %*                                                      *
277 %*********************************************************
278
279 \begin{code}
280 data IOMode      =  ReadMode | WriteMode | AppendMode | ReadWriteMode
281                     deriving (Eq, Ord, Ix, Enum, Read, Show)
282
283 data IOModeEx 
284  = BinaryMode IOMode
285  | TextMode   IOMode
286    deriving (Eq, Read, Show)
287
288 openFile :: FilePath -> IOMode -> IO Handle
289 openFile fp im = openFileEx fp (TextMode im)
290
291 openFileEx :: FilePath -> IOModeEx -> IO Handle
292
293 openFileEx f m = do
294     fo <- CCALL(openFile) (primPackString f) (file_mode::Int) 
295                                              (binary::Int)
296                                              (file_flags::Int) -- ConcHask: SAFE, won't block
297     if fo /= nullAddr then do
298 #ifndef __PARALLEL_HASKELL__
299         fo  <- makeForeignObj fo
300         addForeignFinaliser fo (freeFileObject fo)
301 #endif
302         (bm, bf_size)  <- getBMode__ fo
303         mkBuffer__ fo bf_size
304         newHandle (Handle__ fo htype bm f)
305       else do
306         constructErrorAndFailWithInfo "openFile" f
307   where
308     (imo, binary) =
309       case m of
310         BinaryMode bmo -> (bmo, 1)
311         TextMode tmo   -> (tmo, 0)
312
313 #ifndef __CONCURRENT_HASKELL__
314     file_flags = file_flags'
315 #else
316         -- See comment next to 'stderr' for why we leave
317         -- non-blocking off for now.
318     file_flags = file_flags' {-+ 128  Don't block on I/O-}
319 #endif
320
321     (file_flags', file_mode) =
322       case imo of
323            AppendMode    -> (1, 0)
324            WriteMode     -> (1, 1)
325            ReadMode      -> (0, 2)
326            ReadWriteMode -> (1, 3)
327
328     htype = case imo of 
329               ReadMode      -> ReadHandle
330               WriteMode     -> WriteHandle
331               AppendMode    -> AppendHandle
332               ReadWriteMode -> ReadWriteHandle
333 \end{code}
334
335 Computation $openFile file mode$ allocates and returns a new, open
336 handle to manage the file {\em file}.  It manages input if {\em mode}
337 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
338 and both input and output if mode is $ReadWriteMode$.
339
340 If the file does not exist and it is opened for output, it should be
341 created as a new file.  If {\em mode} is $WriteMode$ and the file
342 already exists, then it should be truncated to zero length.  The
343 handle is positioned at the end of the file if {\em mode} is
344 $AppendMode$, and otherwise at the beginning (in which case its
345 internal position is 0).
346
347 Implementations should enforce, locally to the Haskell process,
348 multiple-reader single-writer locking on files, which is to say that
349 there may either be many handles on the same file which manage input,
350 or just one handle on the file which manages output.  If any open or
351 semi-closed handle is managing a file for output, no new handle can be
352 allocated for that file.  If any open or semi-closed handle is
353 managing a file for input, new handles can only be allocated if they
354 do not manage output.
355
356 Two files are the same if they have the same absolute name.  An
357 implementation is free to impose stricter conditions.
358
359 \begin{code}
360 hClose :: Handle -> IO ()
361
362 hClose handle =
363     withHandle handle $ \ handle_ -> do
364     case haType__ handle_ of 
365       ErrorHandle theError -> do
366           writeHandle handle handle_
367           ioError theError
368       ClosedHandle -> do
369           writeHandle handle handle_
370           ioe_closedHandle "hClose" handle 
371       _ -> do
372           rc      <- CCALL(closeFile) (haFO__ handle_) (1::Int){-flush if you can-}  -- ConcHask: SAFE, won't block
373           {- We explicitly close a file object so that we can be told
374              if there were any errors. Note that after @hClose@
375              has been performed, the ForeignObj embedded in the Handle
376              is still lying around in the heap, so care is taken
377              to avoid closing the file object when the ForeignObj
378              is finalised. (we overwrite the file ptr in the underlying
379              FileObject with a NULL as part of closeFile())
380           -}
381           if rc == (0::Int)
382            then
383               writeHandle handle (handle_{ haType__   = ClosedHandle,
384                                            haFO__     = nullFile__ })
385            else do
386              writeHandle handle handle_
387              constructErrorAndFail "hClose"
388
389 \end{code}
390
391 Computation $hClose hdl$ makes handle {\em hdl} closed.  Before the
392 computation finishes, any items buffered for output and not already
393 sent to the operating system are flushed as for $flush$.
394
395 %*********************************************************
396 %*                                                      *
397 \subsection[EOF]{Detecting the End of Input}
398 %*                                                      *
399 %*********************************************************
400
401
402 For a handle {\em hdl} which attached to a physical file, $hFileSize
403 hdl$ returns the size of {\em hdl} in terms of the number of items
404 which can be read from {\em hdl}.
405
406 \begin{code}
407 hFileSize :: Handle -> IO Integer
408 hFileSize handle =
409     withHandle handle $ \ handle_ -> do
410     case haType__ handle_ of 
411       ErrorHandle theError -> do
412           writeHandle handle handle_
413           ioError theError
414       ClosedHandle -> do
415           writeHandle handle handle_
416           ioe_closedHandle "hFileSize" handle
417       SemiClosedHandle -> do
418           writeHandle handle handle_
419           ioe_closedHandle "hFileSize" handle
420 #ifdef __HUGS__
421       _ -> do
422           mem <- primNewByteArray sizeof_int64
423           rc <- CCALL(fileSize_int64) (haFO__ handle_) mem  -- ConcHask: SAFE, won't block
424           writeHandle handle handle_
425           if rc == 0 then do
426              result <- primReadInt64Array mem 0
427              return (primInt64ToInteger result)
428            else 
429              constructErrorAndFail "hFileSize"
430 #else
431       _ ->
432           -- HACK!  We build a unique MP_INT of the right shape to hold
433           -- a single unsigned word, and we let the C routine 
434           -- change the data bits
435           --
436           -- For some reason, this fails to typecheck if converted to a do
437           -- expression --SDM
438           _casm_ ``%r = 1;'' >>= \(I# hack#) ->
439           case int2Integer hack# of
440             result@(J# _ _ d#) -> do
441                 rc <- CCALL(fileSize) (haFO__ handle_) d#  -- ConcHask: SAFE, won't block
442                 writeHandle handle handle_
443                 if rc == (0::Int) then
444                    return result
445                  else
446                    constructErrorAndFail "hFileSize"
447 #endif
448 \end{code}
449
450 For a readable handle {\em hdl}, @hIsEOF hdl@ returns
451 @True@ if no further input can be taken from @hdl@ or for a
452 physical file, if the current I/O position is equal to the length of
453 the file.  Otherwise, it returns @False@.
454
455 \begin{code}
456 hIsEOF :: Handle -> IO Bool
457 hIsEOF handle =
458     wantReadableHandle "hIsEOF" handle $ \ handle_ -> do
459     let fo = haFO__ handle_
460     rc      <- mayBlock fo (CCALL(fileEOF) fo)  -- ConcHask: UNSAFE, may block
461     writeHandle handle handle_
462     case rc of
463       0 -> return False
464       1 -> return True
465       _ -> constructErrorAndFail "hIsEOF"
466
467 isEOF :: IO Bool
468 isEOF = hIsEOF stdin
469 \end{code}
470
471 %*********************************************************
472 %*                                                      *
473 \subsection[Buffering]{Buffering Operations}
474 %*                                                      *
475 %*********************************************************
476
477 Three kinds of buffering are supported: line-buffering, 
478 block-buffering or no-buffering.  See @IOBase@ for definition
479 and further explanation of what the type represent.
480
481 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
482 handle {\em hdl} on subsequent reads and writes.
483
484 \begin{itemize}
485 \item
486 If {\em mode} is @LineBuffering@, line-buffering should be
487 enabled if possible.
488 \item
489 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
490 should be enabled if possible.  The size of the buffer is {\em n} items
491 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
492 \item
493 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
494 \end{itemize}
495
496 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
497 to @NoBuffering@, then any items in the output buffer are written to
498 the device, and any items in the input buffer are discarded.  The
499 default buffering mode when a handle is opened is
500 implementation-dependent and may depend on the object which is
501 attached to that handle.
502
503 \begin{code}
504 hSetBuffering :: Handle -> BufferMode -> IO ()
505
506 hSetBuffering handle mode =
507     case mode of
508       BlockBuffering (Just n) 
509         | n <= 0 -> ioError
510                          (IOError (Just handle)
511                                   InvalidArgument
512                                   "hSetBuffering"
513                                   ("illegal buffer size " ++ showsPrec 9 n []))  -- 9 => should be parens'ified.
514       _ ->
515           withHandle handle $ \ handle_ -> do
516           case haType__ handle_ of
517              ErrorHandle theError -> do
518                 writeHandle handle handle_
519                 ioError theError
520              ClosedHandle -> do
521                 writeHandle handle handle_
522                 ioe_closedHandle "hSetBuffering" handle
523              _ -> do
524                 {- Note:
525                     - we flush the old buffer regardless of whether
526                       the new buffer could fit the contents of the old buffer 
527                       or not.
528                     - allow a handle's buffering to change even if IO has
529                       occurred (ANSI C spec. does not allow this, nor did
530                       the previous implementation of IO.hSetBuffering).
531                     - a non-standard extension is to allow the buffering
532                       of semi-closed handles to change [sof 6/98]
533                 -}
534                 let fo = haFO__ handle_
535                 rc <- mayBlock fo (CCALL(setBuffering) fo bsize) -- ConcHask: UNSAFE, may block
536                 if rc == 0 
537                  then do
538                    writeHandle handle (handle_{ haBufferMode__ = mode })
539                  else do
540                    -- Note: failure to change the buffer size will cause old buffer to be flushed.
541                    writeHandle handle handle_
542                    constructErrorAndFail "hSetBuffering"
543   where
544     bsize :: Int
545     bsize = case mode of
546               NoBuffering             ->  0
547               LineBuffering           -> -1
548               BlockBuffering Nothing  -> -2
549               BlockBuffering (Just n) ->  n
550 \end{code}
551
552 The action @hFlush hdl@ causes any items buffered for output
553 in handle {\em hdl} to be sent immediately to the operating
554 system.
555
556 \begin{code}
557 hFlush :: Handle -> IO () 
558 hFlush handle =
559     wantWriteableHandle "hFlush" handle $ \ handle_ -> do
560     let fo = haFO__ handle_
561     rc      <- mayBlock fo (CCALL(flushFile) fo)   -- ConcHask: UNSAFE, may block
562     writeHandle handle handle_
563     if rc == 0 then 
564        return ()
565      else
566        constructErrorAndFail "hFlush"
567
568 \end{code}
569
570
571 %*********************************************************
572 %*                                                      *
573 \subsection[Seeking]{Repositioning Handles}
574 %*                                                      *
575 %*********************************************************
576
577 \begin{code}
578 data HandlePosn
579  = HandlePosn 
580         Handle   -- Q: should this be a weak or strong ref. to the handle?
581         Int
582
583 data SeekMode    =  AbsoluteSeek | RelativeSeek | SeekFromEnd
584                     deriving (Eq, Ord, Ix, Enum, Read, Show)
585 \end{code}
586
587 Computation @hGetPosn hdl@ returns the current I/O
588 position of {\em hdl} as an abstract position.  Computation
589 $hSetPosn p$ sets the position of {\em hdl}
590 to a previously obtained position {\em p}.
591
592 \begin{code}
593 hGetPosn :: Handle -> IO HandlePosn
594 hGetPosn handle =
595     wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
596     posn    <- CCALL(getFilePosn) (haFO__ handle_)   -- ConcHask: SAFE, won't block
597     writeHandle handle handle_
598     if posn /= -1 then
599       return (HandlePosn handle posn)
600      else
601       constructErrorAndFail "hGetPosn"
602
603 hSetPosn :: HandlePosn -> IO () 
604 hSetPosn (HandlePosn handle posn) = 
605     wantSeekableHandle "hSetPosn" handle $ \ handle_ -> do -- not as silly as it looks: the handle may have been closed in the meantime.
606     let fo = haFO__ handle_
607     rc     <- mayBlock fo (CCALL(setFilePosn) fo posn)    -- ConcHask: UNSAFE, may block
608     writeHandle handle handle_
609     if rc == 0 then 
610        return ()
611      else
612         constructErrorAndFail "hSetPosn"
613 \end{code}
614
615 The action @hSeek hdl mode i@ sets the position of handle
616 @hdl@ depending on @mode@.  If @mode@ is
617 \begin{itemize}
618 \item[{\bf AbsoluteSeek}] The position of @hdl@ is set to @i@.
619 \item[{\bf RelativeSeek}] The position of @hdl@ is set to offset @i@ from
620 the current position.
621 \item[{\bf SeekFromEnd}] The position of @hdl@ is set to offset @i@ from
622 the end of the file.
623 \end{itemize}
624
625 Some handles may not be seekable (see @hIsSeekable@), or only support a
626 subset of the possible positioning operations (e.g. it may only be
627 possible to seek to the end of a tape, or to a positive offset from
628 the beginning or current position).
629
630 It is not possible to set a negative I/O position, or for a physical
631 file, an I/O position beyond the current end-of-file. 
632
633 Note: 
634  - when seeking using @SeekFromEnd@, positive offsets (>=0) means seeking
635    at or past EOF.
636  - relative seeking on buffered handles can lead to non-obvious results.
637
638 \begin{code}
639 hSeek :: Handle -> SeekMode -> Integer -> IO () 
640 #ifdef __HUGS__
641 hSeek handle mode offset = 
642     wantSeekableHandle "hSeek" handle $ \ handle_ -> do
643     let fo = haFO__ handle_
644     rc      <- mayBlock fo (CCALL(seekFile_int64) fo whence (primIntegerToInt64 offset))  -- ConcHask: UNSAFE, may block
645 #else
646 hSeek handle mode (J# _ s# d#) =
647     wantSeekableHandle "hSeek" handle $ \ handle_ -> do
648     let fo = haFO__ handle_
649     rc      <- mayBlock fo (CCALL(seekFile) fo whence (I# s#) d#)  -- ConcHask: UNSAFE, may block
650 #endif
651     writeHandle handle handle_
652     if rc == 0 then 
653        return ()
654      else
655         constructErrorAndFail "hSeek"
656   where
657     whence :: Int
658     whence = case mode of
659                AbsoluteSeek -> 0
660                RelativeSeek -> 1
661                SeekFromEnd  -> 2
662 \end{code}
663
664 %*********************************************************
665 %*                                                      *
666 \subsection[Query]{Handle Properties}
667 %*                                                      *
668 %*********************************************************
669
670 A number of operations return information about the properties of a
671 handle.  Each of these operations returns $True$ if the
672 handle has the specified property, and $False$
673 otherwise.
674
675 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
676 {\em hdl} is not block-buffered.  Otherwise it returns 
677 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and 
678 $( Just n )$ for block-buffering of {\em n} bytes.
679
680 \begin{code}
681 hIsOpen :: Handle -> IO Bool
682 hIsOpen handle =
683     withHandle handle $ \ handle_ -> do
684     case haType__ handle_ of 
685       ErrorHandle theError -> do
686           writeHandle handle handle_
687           ioError theError
688       ClosedHandle -> do
689           writeHandle handle handle_
690           return False
691       SemiClosedHandle -> do
692           writeHandle handle handle_
693           return False
694       _ -> do
695           writeHandle handle handle_
696           return True
697
698 hIsClosed :: Handle -> IO Bool
699 hIsClosed handle =
700     withHandle handle $ \ handle_ -> do
701     case haType__ handle_ of 
702       ErrorHandle theError -> do
703           writeHandle handle handle_
704           ioError theError
705       ClosedHandle -> do
706           writeHandle handle handle_
707           return True
708       _ -> do
709           writeHandle handle handle_
710           return False
711
712 {- not defined, nor exported, but mentioned
713    here for documentation purposes:
714
715     hSemiClosed :: Handle -> IO Bool
716     hSemiClosed h = do
717        ho <- hIsOpen h
718        hc <- hIsClosed h
719        return (not (ho || hc))
720 -}
721
722 hIsReadable :: Handle -> IO Bool
723 hIsReadable handle =
724     withHandle handle $ \ handle_ -> do
725     case haType__ handle_ of 
726       ErrorHandle theError -> do
727           writeHandle handle handle_
728           ioError theError
729       ClosedHandle -> do
730           writeHandle handle handle_
731           ioe_closedHandle "hIsReadable" handle
732       SemiClosedHandle -> do
733           writeHandle handle handle_
734           ioe_closedHandle "hIsReadable" handle
735       htype -> do
736           writeHandle handle handle_
737           return (isReadable htype)
738   where
739     isReadable ReadHandle      = True
740     isReadable ReadWriteHandle = True
741     isReadable _               = False
742
743 hIsWritable :: Handle -> IO Bool
744 hIsWritable handle =
745     withHandle handle $ \ handle_ -> do
746     case haType__ handle_ of 
747       ErrorHandle theError -> do
748           writeHandle handle handle_
749           ioError theError
750       ClosedHandle -> do
751           writeHandle handle handle_
752           ioe_closedHandle "hIsWritable" handle
753       SemiClosedHandle -> do
754           writeHandle handle handle_
755           ioe_closedHandle "hIsWritable" handle
756       htype -> do
757           writeHandle handle handle_
758           return (isWritable htype)
759   where
760     isWritable AppendHandle    = True
761     isWritable WriteHandle     = True
762     isWritable ReadWriteHandle = True
763     isWritable _               = False
764
765
766 #ifndef __PARALLEL_HASKELL__
767 getBMode__ :: ForeignObj -> IO (BufferMode, Int)
768 #else
769 getBMode__ :: Addr -> IO (BufferMode, Int)
770 #endif
771 getBMode__ fo = do
772   rc <- CCALL(getBufferMode) fo    -- ConcHask: SAFE, won't block
773   case (rc::Int) of
774     0  -> return (NoBuffering, 0)
775     -1 -> return (LineBuffering, default_buffer_size)
776     -2 -> return (BlockBuffering Nothing, default_buffer_size)
777     -3 -> return (NoBuffering, 0)               -- only happens on un-stat()able files.
778     n  -> return (BlockBuffering (Just n), n)
779  where
780    default_buffer_size :: Int
781    default_buffer_size = (const_BUFSIZ - 1)
782 \end{code}
783
784 Querying how a handle buffers its data:
785
786 \begin{code}
787 hGetBuffering :: Handle -> IO BufferMode
788 hGetBuffering handle = 
789     withHandle handle $ \ handle_ -> do
790     case haType__ handle_ of 
791       ErrorHandle theError -> do
792           writeHandle handle handle_
793           ioError theError
794       ClosedHandle -> do
795           writeHandle handle handle_
796           ioe_closedHandle "hGetBuffering" handle
797       _ -> do
798           {-
799            We're being non-standard here, and allow the buffering
800            of a semi-closed handle to be queried.   -- sof 6/98
801           -}
802           let v = haBufferMode__ handle_
803           writeHandle handle handle_
804           return v  -- could be stricter..
805
806 \end{code}
807
808 \begin{code}
809 hIsSeekable :: Handle -> IO Bool
810 hIsSeekable handle =
811     withHandle handle $ \ handle_ -> do
812     case haType__ handle_ of 
813       ErrorHandle theError -> do
814           writeHandle handle handle_
815           ioError theError
816       ClosedHandle -> do
817           writeHandle handle handle_
818           ioe_closedHandle "hIsSeekable" handle
819       SemiClosedHandle -> do
820           writeHandle handle handle_
821           ioe_closedHandle "hIsSeekable" handle
822       AppendHandle -> do
823           writeHandle handle handle_
824           return False
825       _ -> do
826           rc <- CCALL(seekFileP) (haFO__ handle_)   -- ConcHask: SAFE, won't block
827           writeHandle handle handle_
828           case (rc::Int) of
829             0 -> return False
830             1 -> return True
831             _ -> constructErrorAndFail "hIsSeekable"
832 \end{code}
833
834
835 %*********************************************************
836 %*                                                      *
837 \subsection{Changing echo status}
838 %*                                                      *
839 %*********************************************************
840
841 Non-standard GHC extension is to allow the echoing status
842 of a handles connected to terminals to be reconfigured:
843
844 \begin{code}
845 hSetEcho :: Handle -> Bool -> IO ()
846 hSetEcho handle on = do
847     isT   <- hIsTerminalDevice handle
848     if not isT
849      then return ()
850      else
851       withHandle handle $ \ handle_ -> do
852       case haType__ handle_ of 
853          ErrorHandle theError ->  do 
854             writeHandle handle handle_
855             ioError theError
856          ClosedHandle      ->  do
857             writeHandle handle handle_
858             ioe_closedHandle "hSetEcho" handle
859          _ -> do
860             rc <- CCALL(setTerminalEcho) (haFO__ handle_) ((if on then 1 else 0)::Int)  -- ConcHask: SAFE, won't block
861             writeHandle handle handle_
862             if rc /= ((-1)::Int)
863              then return ()
864              else constructErrorAndFail "hSetEcho"
865
866 hGetEcho :: Handle -> IO Bool
867 hGetEcho handle = do
868     isT   <- hIsTerminalDevice handle
869     if not isT
870      then return False
871      else
872        withHandle handle $ \ handle_ -> do
873        case haType__ handle_ of 
874          ErrorHandle theError ->  do 
875             writeHandle handle handle_
876             ioError theError
877          ClosedHandle      ->  do
878             writeHandle handle handle_
879             ioe_closedHandle "hGetEcho" handle
880          _ -> do
881             rc <- CCALL(getTerminalEcho) (haFO__ handle_)  -- ConcHask: SAFE, won't block
882             writeHandle handle handle_
883             case (rc::Int) of
884               1 -> return True
885               0 -> return False
886               _ -> constructErrorAndFail "hSetEcho"
887
888 hIsTerminalDevice :: Handle -> IO Bool
889 hIsTerminalDevice handle = do
890     withHandle handle $ \ handle_ -> do
891     case haType__ handle_ of 
892        ErrorHandle theError ->  do 
893             writeHandle handle handle_
894             ioError theError
895        ClosedHandle        ->  do
896             writeHandle handle handle_
897             ioe_closedHandle "hIsTerminalDevice" handle
898        _ -> do
899           rc <- CCALL(isTerminalDevice) (haFO__ handle_)   -- ConcHask: SAFE, won't block
900           writeHandle handle handle_
901           case (rc::Int) of
902             1 -> return True
903             0 -> return False
904             _ -> constructErrorAndFail "hIsTerminalDevice"
905 \end{code}
906
907 \begin{code}
908 hConnectTerms :: Handle -> Handle -> IO ()
909 hConnectTerms hW hR = hConnectHdl_ hW hR 1{-check if they're both coming connected to ttys-}
910
911 hConnectTo :: Handle -> Handle -> IO ()
912 hConnectTo hW hR = hConnectHdl_ hW hR 0{-connect regardless-}
913
914 hConnectHdl_ :: Handle -> Handle -> Int -> IO ()
915 hConnectHdl_ hW hR is_tty = 
916   wantRWHandle "hConnectTo" hW $ \ hW_ -> do
917   wantRWHandle "hConnectTo" hR $ \ hR_ -> do
918   CCALL(setConnectedTo) (haFO__ hR_) (haFO__ hW_) is_tty  -- ConcHask: SAFE, won't block
919   writeHandle hR hR_
920   writeHandle hW hW_
921
922 #ifndef __PARALLEL_HASKELL__
923 #define FILE_OBJECT     ForeignObj
924 #else
925 #define FILE_OBJECT     Addr
926 #endif
927
928 flushConnectedBuf :: FILE_OBJECT -> IO ()
929 flushConnectedBuf fo = CCALL(flushConnectedBuf) fo
930 \end{code}
931
932 As an extension, we also allow characters to be pushed back.
933 Like ANSI C stdio, we guarantee no more than one character of
934 pushback. (For unbuffered channels, the (default) push-back limit is
935 2 chars tho.)
936
937 \begin{code}
938 hUngetChar :: Handle -> Char -> IO ()
939 hUngetChar handle c = 
940     wantReadableHandle "hLookAhead" handle $ \ handle_ -> do
941     rc      <- CCALL(ungetChar) (haFO__ handle_) c  -- ConcHask: SAFE, won't block
942     writeHandle handle handle_
943     if rc == ((-1)::Int)
944      then constructErrorAndFail "hUngetChar"
945      else return ()
946
947 \end{code}
948
949
950 Hoisting files in in one go is sometimes useful, so we support
951 this as an extension:
952
953 \begin{code}
954 -- in one go, read file into an externally allocated buffer.
955 slurpFile :: FilePath -> IO (Addr, Int)
956 slurpFile fname = do
957   handle <- openFile fname ReadMode
958   sz     <- hFileSize handle
959   if sz > toInteger (maxBound::Int) then 
960     ioError (userError "slurpFile: file too big")
961    else do
962      let sz_i = fromInteger sz
963      chunk <- CCALL(allocMemory__) (sz_i::Int)
964      if chunk == nullAddr 
965       then do
966         hClose handle
967         constructErrorAndFail "slurpFile"
968       else
969         withHandle handle $ \ handle_ -> do
970         let fo = haFO__ handle_
971         rc      <- mayBlock fo (CCALL(readChunk) fo chunk sz_i)    -- ConcHask: UNSAFE, may block.
972         writeHandle handle handle_
973         hClose handle
974         if rc < (0::Int)
975          then constructErrorAndFail "slurpFile"
976          else return (chunk, rc)
977
978 #ifndef __HUGS__ /* Hugs' Prelude doesn't need this */
979 hFillBufBA :: Handle -> ByteArray Int -> Int -> IO Int
980 hFillBufBA handle buf sz
981   | sz <= 0 = ioError (IOError (Just handle)
982                             InvalidArgument
983                             "hFillBufBA"
984                             ("illegal buffer size " ++ showsPrec 9 sz []))  -- 9 => should be parens'ified.
985   | otherwise = 
986     wantReadableHandle "hFillBufBA" handle $ \ handle_ -> do
987     let fo  = haFO__ handle_
988 #ifdef __HUGS__
989     rc      <- mayBlock fo (CCALL(readChunkBA) fo buf sz)    -- ConcHask: UNSAFE, may block.
990 #else
991     rc      <- mayBlock fo (CCALL(readChunk) fo buf sz)    -- ConcHask: UNSAFE, may block.
992 #endif
993     writeHandle handle handle_
994     if rc >= (0::Int)
995      then return rc
996      else constructErrorAndFail "hFillBufBA"
997 #endif
998
999 hFillBuf :: Handle -> Addr -> Int -> IO Int
1000 hFillBuf handle buf sz
1001   | sz <= 0 = ioError (IOError (Just handle)
1002                             InvalidArgument
1003                             "hFillBuf"
1004                             ("illegal buffer size " ++ showsPrec 9 sz []))  -- 9 => should be parens'ified.
1005   | otherwise = 
1006     wantReadableHandle "hFillBuf" handle $ \ handle_ -> do
1007     let fo  = haFO__ handle_
1008     rc      <- mayBlock fo (CCALL(readChunk) fo buf sz)    -- ConcHask: UNSAFE, may block.
1009     writeHandle handle handle_
1010     if rc >= 0
1011      then return rc
1012      else constructErrorAndFail "hFillBuf"
1013
1014 \end{code}
1015
1016 The @hPutBuf hdl buf len@ action writes an already packed sequence of
1017 bytes to the file/channel managed by @hdl@ - non-standard.
1018
1019 \begin{code}
1020 hPutBuf :: Handle -> Addr -> Int -> IO ()
1021 hPutBuf handle buf len = 
1022     wantWriteableHandle "hPutBuf" handle $ \ handle_ -> do
1023     let fo  = haFO__ handle_
1024     rc      <- mayBlock fo (CCALL(writeBuf) fo buf len)  -- ConcHask: UNSAFE, may block.
1025     writeHandle handle handle_
1026     if rc == (0::Int)
1027      then return ()
1028      else constructErrorAndFail "hPutBuf"
1029
1030 #ifndef __HUGS__ /* An_ one Hugs doesn't provide */
1031 hPutBufBA :: Handle -> ByteArray Int -> Int -> IO ()
1032 hPutBufBA handle buf len =
1033     wantWriteableHandle "hPutBufBA" handle $ \ handle_ -> do
1034     let fo = haFO__ handle_
1035     rc      <- mayBlock fo (CCALL(writeBufBA) fo buf len)  -- ConcHask: UNSAFE, may block.
1036     writeHandle handle handle_
1037     if rc == (0::Int)
1038      then return ()
1039      else constructErrorAndFail "hPutBuf"
1040 #endif
1041 \end{code}
1042
1043 Sometimes it's useful to get at the file descriptor that
1044 the Handle contains..
1045
1046 \begin{code}
1047 getHandleFd :: Handle -> IO Int
1048 getHandleFd handle = do
1049     withHandle handle $ \ handle_ -> do
1050     case (haType__ handle_) of
1051       ErrorHandle theError -> do
1052           writeHandle handle handle_
1053           ioError theError
1054       ClosedHandle -> do
1055           writeHandle handle handle_
1056           ioe_closedHandle "getHandleFd" handle
1057       _ -> do
1058           fd <- CCALL(getFileFd) (haFO__ handle_)
1059           writeHandle handle handle_
1060           return fd
1061 \end{code}
1062
1063
1064 %*********************************************************
1065 %*                                                      *
1066 \subsection{Miscellaneous}
1067 %*                                                      *
1068 %*********************************************************
1069
1070 These three functions are meant to get things out of @IOErrors@.
1071
1072 (ToDo: improve!)
1073
1074 \begin{code}
1075 ioeGetFileName        :: IOError -> Maybe FilePath
1076 ioeGetErrorString     :: IOError -> String
1077 ioeGetHandle          :: IOError -> Maybe Handle
1078
1079 ioeGetHandle   (IOError h _ _ _)   = h
1080 ioeGetErrorString (IOError _ iot _ str) =
1081  case iot of
1082    EOF -> "end of file"
1083    _   -> str
1084
1085 ioeGetFileName (IOError _ _  _ str) = 
1086  case span (/=':') str of
1087    (_,[])  -> Nothing
1088    (fs,_)  -> Just fs
1089
1090 \end{code}
1091
1092 A number of operations want to get at a readable or writeable handle, and fail
1093 if it isn't:
1094
1095 \begin{code}
1096 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1097 wantReadableHandle fun handle act = 
1098     withHandle handle $ \ handle_ -> do
1099     case haType__ handle_ of 
1100       ErrorHandle theError -> do
1101           writeHandle handle handle_
1102           ioError theError
1103       ClosedHandle -> do
1104           writeHandle handle handle_
1105           ioe_closedHandle fun handle
1106       SemiClosedHandle -> do
1107           writeHandle handle handle_
1108           ioe_closedHandle fun handle
1109       AppendHandle -> do
1110           writeHandle handle handle_
1111           ioError not_readable_error
1112       WriteHandle -> do
1113           writeHandle handle handle_
1114           ioError not_readable_error
1115       _ -> act handle_
1116   where
1117    not_readable_error = 
1118            IOError (Just handle) IllegalOperation fun   
1119                    ("handle is not open for reading")
1120
1121 wantWriteableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1122 wantWriteableHandle fun handle act = 
1123     withHandle handle $ \ handle_ -> do
1124     case haType__ handle_ of 
1125       ErrorHandle theError -> do
1126           writeHandle handle handle_
1127           ioError theError
1128       ClosedHandle -> do
1129           writeHandle handle handle_
1130           ioe_closedHandle fun handle
1131       SemiClosedHandle -> do
1132           writeHandle handle handle_
1133           ioe_closedHandle fun handle
1134       ReadHandle -> do
1135           writeHandle handle handle_
1136           ioError not_writeable_error
1137       _ -> act handle_
1138   where
1139    not_writeable_error = 
1140            IOError (Just handle) IllegalOperation fun
1141                    ("handle is not open for writing")
1142
1143 wantRWHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1144 wantRWHandle fun handle act = 
1145     withHandle handle $ \ handle_ -> do
1146     case haType__ handle_ of 
1147       ErrorHandle theError -> do
1148           writeHandle handle handle_
1149           ioError theError
1150       ClosedHandle -> do
1151           writeHandle handle handle_
1152           ioe_closedHandle fun handle
1153       SemiClosedHandle -> do
1154           writeHandle handle handle_
1155           ioe_closedHandle fun handle
1156       _ -> act handle_
1157   where
1158    not_rw_error = 
1159            IOError (Just handle) IllegalOperation fun
1160                    ("handle is not open for reading or writing")
1161
1162 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1163 wantSeekableHandle fun handle act =
1164     withHandle handle $ \ handle_ -> do
1165     case haType__ handle_ of 
1166       ErrorHandle theError -> do
1167           writeHandle handle handle_
1168           ioError theError
1169       ClosedHandle -> do
1170           writeHandle handle handle_
1171           ioe_closedHandle fun handle
1172       SemiClosedHandle -> do
1173           writeHandle handle handle_
1174           ioe_closedHandle fun handle
1175       AppendHandle -> do
1176           writeHandle handle handle_
1177           ioError not_seekable_error
1178       _ -> act handle_
1179   where
1180    not_seekable_error = 
1181            IOError (Just handle) 
1182                    IllegalOperation fun
1183                    ("handle is not seekable")
1184
1185 \end{code}
1186
1187 Internal function for creating an @IOError@ representing the
1188 access to a closed file.
1189
1190 \begin{code}
1191 ioe_closedHandle :: String -> Handle -> IO a
1192 ioe_closedHandle fun h = ioError (IOError (Just h) IllegalOperation fun "handle is closed")
1193 \end{code}
1194
1195 Internal helper functions for Concurrent Haskell implementation
1196 of IO:
1197
1198 \begin{code}
1199 #ifndef __PARALLEL_HASKELL__
1200 mayBlock :: ForeignObj -> IO Int -> IO Int
1201 #else
1202 mayBlock :: Addr  -> IO Int -> IO Int
1203 #endif
1204
1205 #ifndef notyet /*__CONCURRENT_HASKELL__*/
1206 mayBlock  _ act = act
1207 #else
1208 mayBlock fo act = do
1209    rc <- act
1210    case rc of
1211      -5 -> do  -- (possibly blocking) read
1212         fd <- CCALL(getFileFd) fo
1213         threadWaitRead fd
1214         CCALL(clearNonBlockingIOFlag__) fo  -- force read to happen this time.
1215         mayBlock fo act  -- input available, re-try
1216      -6 -> do  -- (possibly blocking) write
1217         fd <- CCALL(getFileFd) fo
1218         threadWaitWrite fd
1219         CCALL(clearNonBlockingIOFlag__) fo  -- force write to happen this time.
1220         mayBlock fo act  -- output possible
1221      -7 -> do  -- (possibly blocking) write on connected handle
1222         fd <- CCALL(getConnFileFd) fo
1223         threadWaitWrite fd
1224         CCALL(clearConnNonBlockingIOFlag__) fo  -- force write to happen this time.
1225         mayBlock fo act  -- output possible
1226      _ -> do
1227         CCALL(setNonBlockingIOFlag__) fo      -- reset file object.
1228         CCALL(setConnNonBlockingIOFlag__) fo  -- reset (connected) file object.
1229         return rc
1230
1231 #endif
1232
1233 -- #ifdef __HUGS__
1234 #if 1
1235 threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
1236
1237 -- Hugs does actually have the primops needed to implement these
1238 -- but, like GHC, the primops don't actually do anything...
1239 threadDelay     _ = return ()
1240 threadWaitRead  _ = return ()
1241 threadWaitWrite _ = return ()
1242 #endif
1243
1244 \end{code}
1245
1246
1247 \begin{code}
1248 #ifdef __HUGS__
1249 type FD           = Int
1250 type Exclusive    = Int  -- really Bool
1251 type How          = Int
1252 type Binary       = Int
1253 type OpenStdFlags = Int
1254 type OpenFlags    = Int
1255 type Readable     = Int  -- really Bool
1256 type Flush        = Int  -- really Bool
1257 type RC           = Int  -- standard return code
1258
1259 type IOFileAddr   = Addr  -- as returned from functions
1260 type CString      = PrimByteArray
1261 type Bytes        = PrimMutableByteArray RealWorld
1262
1263 #ifndef __PARALLEL_HASKELL__
1264 type FILE_OBJ  = ForeignObj -- as passed into functions
1265 #else
1266 type FILE_OBJ  = Addr
1267 #endif
1268
1269 foreign import ccall "libHS_cbits.so" "setBuf"                unsafe prim_setBuf           :: FILE_OBJ -> Addr -> Int -> IO ()
1270 foreign import ccall "libHS_cbits.so" "getBufSize"            unsafe prim_getBufSize       :: FILE_OBJ -> IO Int
1271 foreign import ccall "libHS_cbits.so" "inputReady"            unsafe prim_inputReady       :: FILE_OBJ -> Int -> IO RC
1272 foreign import ccall "libHS_cbits.so" "fileGetc"              unsafe prim_fileGetc         :: FILE_OBJ -> IO Int
1273 foreign import ccall "libHS_cbits.so" "fileLookAhead"         unsafe prim_fileLookAhead    :: FILE_OBJ -> IO Int
1274 foreign import ccall "libHS_cbits.so" "readBlock"             unsafe prim_readBlock        :: FILE_OBJ -> IO Int
1275 foreign import ccall "libHS_cbits.so" "readLine"              unsafe prim_readLine         :: FILE_OBJ -> IO Int
1276 foreign import ccall "libHS_cbits.so" "readChar"              unsafe prim_readChar         :: FILE_OBJ -> IO Int
1277 foreign import ccall "libHS_cbits.so" "writeFileObject"       unsafe prim_writeFileObject  :: FILE_OBJ -> Int -> IO RC
1278 foreign import ccall "libHS_cbits.so" "filePutc"              unsafe prim_filePutc         :: FILE_OBJ -> Char -> IO RC
1279 foreign import ccall "libHS_cbits.so" "getBufStart"           unsafe prim_getBufStart      :: FILE_OBJ -> Int -> IO Addr
1280 foreign import ccall "libHS_cbits.so" "getWriteableBuf"       unsafe prim_getWriteableBuf  :: FILE_OBJ -> IO Addr
1281 foreign import ccall "libHS_cbits.so" "getBufWPtr"            unsafe prim_getBufWPtr       :: FILE_OBJ -> IO Int
1282 foreign import ccall "libHS_cbits.so" "setBufWPtr"            unsafe prim_setBufWPtr       :: FILE_OBJ -> Int -> IO ()
1283 foreign import ccall "libHS_cbits.so" "closeFile"             unsafe prim_closeFile        :: FILE_OBJ -> Flush -> IO RC
1284 foreign import ccall "libHS_cbits.so" "fileEOF"               unsafe prim_fileEOF           :: FILE_OBJ -> IO RC
1285 foreign import ccall "libHS_cbits.so" "setBuffering"          unsafe prim_setBuffering      :: FILE_OBJ -> Int -> IO RC
1286 foreign import ccall "libHS_cbits.so" "flushFile"             unsafe prim_flushFile         :: FILE_OBJ -> IO RC
1287 foreign import ccall "libHS_cbits.so" "flushConnectedBuf"     unsafe prim_flushConnectedBuf :: FILE_OBJ -> IO RC
1288 foreign import ccall "libHS_cbits.so" "getBufferMode"         unsafe prim_getBufferMode     :: FILE_OBJ -> IO RC
1289 foreign import ccall "libHS_cbits.so" "seekFile_int64"        unsafe prim_seekFile_int64    :: FILE_OBJ -> Int -> Int64 -> IO RC
1290 foreign import ccall "libHS_cbits.so" "seekFileP"             unsafe prim_seekFileP        :: FILE_OBJ -> IO RC
1291 foreign import ccall "libHS_cbits.so" "setTerminalEcho"       unsafe prim_setTerminalEcho  :: FILE_OBJ -> Int -> IO RC
1292 foreign import ccall "libHS_cbits.so" "getTerminalEcho"       unsafe prim_getTerminalEcho  :: FILE_OBJ -> IO RC
1293 foreign import ccall "libHS_cbits.so" "isTerminalDevice"      unsafe prim_isTerminalDevice :: FILE_OBJ -> IO RC
1294 foreign import ccall "libHS_cbits.so" "setConnectedTo"        unsafe prim_setConnectedTo   :: FILE_OBJ -> FILE_OBJ -> Int -> IO ()
1295 foreign import ccall "libHS_cbits.so" "ungetChar"             unsafe prim_ungetChar        :: FILE_OBJ -> Char -> IO RC
1296 foreign import ccall "libHS_cbits.so" "readChunk"             unsafe prim_readChunk        :: FILE_OBJ -> Addr          -> Int -> IO RC
1297 foreign import ccall "libHS_cbits.so" "writeBuf"              unsafe prim_writeBuf         :: FILE_OBJ -> Addr -> Int -> IO RC
1298 foreign import ccall "libHS_cbits.so" "getFileFd"             unsafe prim_getFileFd        :: FILE_OBJ -> IO FD
1299 foreign import ccall "libHS_cbits.so" "fileSize_int64"        unsafe prim_fileSize_int64   :: FILE_OBJ -> Bytes -> IO RC
1300 foreign import ccall "libHS_cbits.so" "getFilePosn"           unsafe prim_getFilePosn      :: FILE_OBJ -> IO Int
1301 foreign import ccall "libHS_cbits.so" "setFilePosn"           unsafe prim_setFilePosn      :: FILE_OBJ -> Int -> IO Int
1302 foreign import ccall "libHS_cbits.so" "getConnFileFd"         unsafe prim_getConnFileFd    :: FILE_OBJ -> IO FD
1303 foreign import ccall "libHS_cbits.so" "allocMemory__"         unsafe prim_allocMemory__    :: Int -> IO Addr
1304 foreign import ccall "libHS_cbits.so" "getLock"               unsafe prim_getLock          :: FD -> Exclusive -> IO RC
1305 foreign import ccall "libHS_cbits.so" "openStdFile"           unsafe prim_openStdFile      :: FD -> OpenStdFlags -> Readable -> IO IOFileAddr
1306 foreign import ccall "libHS_cbits.so" "openFile"              unsafe prim_openFile         :: CString -> How -> Binary -> OpenFlags -> IO IOFileAddr
1307 foreign import ccall "libHS_cbits.so" "freeFileObject"        unsafe prim_freeFileObject    :: FILE_OBJ -> IO ()
1308 foreign import ccall "libHS_cbits.so" "freeStdFileObject"     unsafe prim_freeStdFileObject :: FILE_OBJ -> IO ()
1309 foreign import ccall "libHS_cbits.so" "const_BUFSIZ"          unsafe const_BUFSIZ          :: Int
1310
1311 foreign import ccall "libHS_cbits.so" "setConnNonBlockingIOFlag__"   unsafe prim_setConnNonBlockingIOFlag__   :: FILE_OBJ -> IO ()
1312 foreign import ccall "libHS_cbits.so" "clearConnNonBlockingIOFlag__" unsafe prim_clearConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
1313 foreign import ccall "libHS_cbits.so" "setNonBlockingIOFlag__"       unsafe prim_setNonBlockingIOFlag__       :: FILE_OBJ -> IO ()
1314 foreign import ccall "libHS_cbits.so" "clearNonBlockingIOFlag__"     unsafe prim_clearNonBlockingIOFlag__     :: FILE_OBJ -> IO ()
1315
1316 foreign import ccall "libHS_cbits.so" "getErrStr__"  unsafe prim_getErrStr__  :: IO Addr 
1317 foreign import ccall "libHS_cbits.so" "getErrNo__"   unsafe prim_getErrNo__   :: IO Int  
1318 foreign import ccall "libHS_cbits.so" "getErrType__" unsafe prim_getErrType__ :: IO Int  
1319
1320 #endif
1321 \end{code}
1322
1323