2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[PrelHandle]{Module @PrelHandle@}
7 This module defines Haskell {\em handles} and the basic operations
8 which are supported for them.
11 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
12 #include "cbits/error.h"
14 #ifndef __HUGS__ /* Hugs just includes this in PreludeBuiltin so no header needed */
15 module PrelHandle where
18 import PrelArr ( newVar, readVar, writeVar, ByteArray )
19 import PrelRead ( Read )
20 import PrelList ( span )
22 import PrelException ( Exception(..), throw, catch, fail, 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__
33 #ifndef __PARALLEL_HASKELL__
34 import PrelForeign ( makeForeignObj, writeForeignObj )
37 #endif /* ndef(__HUGS__) */
40 #define cat2(x,y) x/**/y
41 #define CCALL(fun) cat2(prim_,fun)
42 #define __CONCURRENT_HASKELL__
44 #define sizeof_int64 8
46 #define CCALL(fun) _ccall_ fun
47 #define const_BUFSIZ ``BUFSIZ''
48 #define primPackString
51 #ifndef __PARALLEL_HASKELL__
52 #define FILE_OBJECT ForeignObj
54 #define FILE_OBJECT Addr
59 %*********************************************************
61 \subsection{Types @Handle@, @Handle__@}
63 %*********************************************************
65 The @Handle@ and @Handle__@ types are defined in @IOBase@.
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 ()
75 #if defined(__CONCURRENT_HASKELL__)
77 -- Use MVars for concurrent Haskell
78 newHandle hc = newMVar hc >>= \ h ->
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
87 v <- catchException (act h_) (\ ex -> putMVar h h_ >> throw ex)
90 writeHandle (Handle h) hc = putMVar h hc
93 -- Use ordinary MutableVars for non-concurrent Haskell
94 newHandle hc = stToIO (newVar hc >>= \ h ->
97 -- of questionable value to install this exception
98 -- handler, but let's do it in the non-concurrent
100 withHandle (Handle h) act = do
101 h_ <- stToIO (readVar h)
102 v <- catchException (act h_) (\ ex -> stToIO (writeVar h h_) >> throw ex)
105 writeHandle (Handle h) hc = stToIO (writeVar h hc)
110 nullFile__ is only used for closed handles, plugging it in as a null
111 file object reference.
114 nullFile__ :: FILE_OBJECT
116 #ifndef __PARALLEL_HASKELL__
117 unsafePerformIO (makeForeignObj nullAddr)
123 mkClosedHandle__ :: Handle__
131 mkErrorHandle__ :: IOError -> Handle__
132 mkErrorHandle__ ioe =
140 %*********************************************************
142 \subsection{Handle Finalisers}
144 %*********************************************************
148 freeStdFileObject :: ForeignObj -> IO ()
149 freeStdFileObject fo = CCALL(freeStdFileObject) fo
151 freeFileObject :: ForeignObj -> IO ()
152 freeFileObject fo = CCALL(freeFileObject) fo
154 foreign import stdcall "libHS_cbits.so" "freeStdFileObject" freeStdFileObject :: ForeignObj -> IO ()
155 foreign import stdcall "libHS_cbits.so" "freeFileObject" freeFileObject :: ForeignObj -> IO ()
159 %*********************************************************
161 \subsection[StdHandles]{Standard handles}
163 %*********************************************************
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.
171 stdin, stdout, stderr :: Handle
173 stdout = unsafePerformIO (do
174 rc <- CCALL(getLock) 1 1 -- ConcHask: SAFE, won't block
176 0 -> newHandle (mkClosedHandle__)
178 #ifndef __CONCURRENT_HASKELL__
179 fo <- CCALL(openStdFile) 1 1{-flush on close-} 0{-writeable-} -- ConcHask: SAFE, won't block
181 fo <- CCALL(openStdFile) 1 (1{-flush on close-} {-+ 128 don't block on I/O-})
182 0{-writeable-} -- ConcHask: SAFE, won't block
185 #ifndef __PARALLEL_HASKELL__
186 fo <- makeForeignObj fo
187 addForeignFinaliser fo (freeStdFileObject fo)
191 /* I dont care what the Haskell report says, in an interactive system,
192 * stdout should be unbuffered by default.
196 (bm, bf_size) <- getBMode__ fo
197 mkBuffer__ fo bf_size
199 newHandle (Handle__ fo WriteHandle bm "stdout")
200 _ -> do ioError <- constructError "stdout"
201 newHandle (mkErrorHandle__ ioError)
204 stdin = unsafePerformIO (do
205 rc <- CCALL(getLock) 0 0 -- ConcHask: SAFE, won't block
207 0 -> newHandle (mkClosedHandle__)
209 #ifndef __CONCURRENT_HASKELL__
210 fo <- CCALL(openStdFile) 0 0{-don't flush on close -} 1{-readable-} -- ConcHask: SAFE, won't block
212 fo <- CCALL(openStdFile) 0 (0{-flush on close-} {- + 128 don't block on I/O-})
213 1{-readable-} -- ConcHask: SAFE, won't block
216 #ifndef __PARALLEL_HASKELL__
217 fo <- makeForeignObj fo
218 addForeignFinaliser fo (freeStdFileObject fo)
220 (bm, bf_size) <- getBMode__ fo
221 mkBuffer__ fo bf_size
222 hdl <- newHandle (Handle__ fo ReadHandle bm "stdin")
223 -- when stdin and stdout are both connected to a terminal, ensure
224 -- that anything buffered on stdout is flushed prior to reading from stdin.
226 hConnectTerms stdout hdl
228 _ -> do ioError <- constructError "stdin"
229 newHandle (mkErrorHandle__ ioError)
233 stderr = unsafePerformIO (do
234 rc <- CCALL(getLock) 2 1 -- ConcHask: SAFE, won't block
236 0 -> newHandle (mkClosedHandle__)
238 #ifndef __CONCURRENT_HASKELL__
239 fo <- CCALL(openStdFile) 2 1{-flush on close-} 0{-writeable-} -- ConcHask: SAFE, won't block
241 fo <- CCALL(openStdFile) 2 (1{-flush on close-} {- + 128 don't block on I/O-})
242 0{-writeable-} -- ConcHask: SAFE, won't block
245 #ifndef __PARALLEL_HASKELL__
246 fo <- makeForeignObj fo
247 addForeignFinaliser fo (freeStdFileObject fo)
249 newHandle (Handle__ fo WriteHandle NoBuffering "stderr")
250 _ -> do ioError <- constructError "stderr"
251 newHandle (mkErrorHandle__ ioError)
255 %*********************************************************
257 \subsection[OpeningClosing]{Opening and Closing Files}
259 %*********************************************************
262 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
263 deriving (Eq, Ord, Ix, Enum, Read, Show)
268 deriving (Eq, Read, Show)
270 openFile :: FilePath -> IOMode -> IO Handle
271 openFile fp im = openFileEx fp (TextMode im)
273 openFileEx :: FilePath -> IOModeEx -> IO Handle
276 fo <- CCALL(openFile) (primPackString f) file_mode binary file_flags -- ConcHask: SAFE, won't block
277 if fo /= nullAddr then do
278 #ifndef __PARALLEL_HASKELL__
279 fo <- makeForeignObj fo
280 addForeignFinaliser fo (freeFileObject fo)
282 (bm, bf_size) <- getBMode__ fo
283 mkBuffer__ fo bf_size
284 newHandle (Handle__ fo htype bm f)
286 constructErrorAndFailWithInfo "openFile" f
290 BinaryMode imo -> (imo, 1)
291 TextMode imo -> (imo, 0)
293 #ifndef __CONCURRENT_HASKELL__
294 file_flags = file_flags'
296 file_flags = file_flags' {-+ 128 Don't block on I/O-}
299 (file_flags', file_mode) =
304 ReadWriteMode -> (1, 3)
307 ReadMode -> ReadHandle
308 WriteMode -> WriteHandle
309 AppendMode -> AppendHandle
310 ReadWriteMode -> ReadWriteHandle
313 Computation $openFile file mode$ allocates and returns a new, open
314 handle to manage the file {\em file}. It manages input if {\em mode}
315 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
316 and both input and output if mode is $ReadWriteMode$.
318 If the file does not exist and it is opened for output, it should be
319 created as a new file. If {\em mode} is $WriteMode$ and the file
320 already exists, then it should be truncated to zero length. The
321 handle is positioned at the end of the file if {\em mode} is
322 $AppendMode$, and otherwise at the beginning (in which case its
323 internal position is 0).
325 Implementations should enforce, locally to the Haskell process,
326 multiple-reader single-writer locking on files, which is to say that
327 there may either be many handles on the same file which manage input,
328 or just one handle on the file which manages output. If any open or
329 semi-closed handle is managing a file for output, no new handle can be
330 allocated for that file. If any open or semi-closed handle is
331 managing a file for input, new handles can only be allocated if they
332 do not manage output.
334 Two files are the same if they have the same absolute name. An
335 implementation is free to impose stricter conditions.
338 hClose :: Handle -> IO ()
341 withHandle handle $ \ handle_ -> do
342 case haType__ handle_ of
343 ErrorHandle ioError -> do
344 writeHandle handle handle_
347 writeHandle handle handle_
348 ioe_closedHandle "hClose" handle
350 rc <- CCALL(closeFile) (haFO__ handle_) 1{-flush if you can-} -- ConcHask: SAFE, won't block
351 {- We explicitly close a file object so that we can be told
352 if there were any errors. Note that after @hClose@
353 has been performed, the ForeignObj embedded in the Handle
354 is still lying around in the heap, so care is taken
355 to avoid closing the file object when the ForeignObj
356 is finalised. (we overwrite the file ptr in the underlying
357 FileObject with a NULL as part of closeFile())
361 writeHandle handle (handle_{ haType__ = ClosedHandle,
362 haFO__ = nullFile__ })
364 writeHandle handle handle_
365 constructErrorAndFail "hClose"
369 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
370 computation finishes, any items buffered for output and not already
371 sent to the operating system are flushed as for $flush$.
373 %*********************************************************
375 \subsection[EOF]{Detecting the End of Input}
377 %*********************************************************
380 For a handle {\em hdl} which attached to a physical file, $hFileSize
381 hdl$ returns the size of {\em hdl} in terms of the number of items
382 which can be read from {\em hdl}.
385 hFileSize :: Handle -> IO Integer
387 withHandle handle $ \ handle_ -> do
388 case haType__ handle_ of
389 ErrorHandle ioError -> do
390 writeHandle handle handle_
393 writeHandle handle handle_
394 ioe_closedHandle "hFileSize" handle
395 SemiClosedHandle -> do
396 writeHandle handle handle_
397 ioe_closedHandle "hFileSize" handle
400 mem <- primNewByteArray sizeof_int64
401 rc <- CCALL(fileSize_int64) (haFO__ handle_) mem -- ConcHask: SAFE, won't block
402 writeHandle handle handle_
404 result <- primReadInt64Array mem 0
405 return (primInt64ToInteger result)
407 constructErrorAndFail "hFileSize"
410 -- HACK! We build a unique MP_INT of the right shape to hold
411 -- a single unsigned word, and we let the C routine
412 -- change the data bits
414 -- For some reason, this fails to typecheck if converted to a do
416 _casm_ ``%r = 1;'' >>= \(I# hack#) ->
417 case int2Integer hack# of
418 result@(J# _ _ d#) -> do
419 rc <- CCALL(fileSize) (haFO__ handle_) d# -- ConcHask: SAFE, won't block
420 writeHandle handle handle_
424 constructErrorAndFail "hFileSize"
428 For a readable handle {\em hdl}, @hIsEOF hdl@ returns
429 @True@ if no further input can be taken from @hdl@ or for a
430 physical file, if the current I/O position is equal to the length of
431 the file. Otherwise, it returns @False@.
434 hIsEOF :: Handle -> IO Bool
436 wantReadableHandle "hIsEOF" handle $ \ handle_ -> do
437 let fo = haFO__ handle_
438 rc <- mayBlock fo (CCALL(fileEOF) fo) -- ConcHask: UNSAFE, may block
439 writeHandle handle handle_
443 _ -> constructErrorAndFail "hIsEOF"
449 %*********************************************************
451 \subsection[Buffering]{Buffering Operations}
453 %*********************************************************
455 Three kinds of buffering are supported: line-buffering,
456 block-buffering or no-buffering. See @IOBase@ for definition
457 and further explanation of what the type represent.
459 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
460 handle {\em hdl} on subsequent reads and writes.
464 If {\em mode} is @LineBuffering@, line-buffering should be
467 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
468 should be enabled if possible. The size of the buffer is {\em n} items
469 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
471 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
474 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
475 to @NoBuffering@, then any items in the output buffer are written to
476 the device, and any items in the input buffer are discarded. The
477 default buffering mode when a handle is opened is
478 implementation-dependent and may depend on the object which is
479 attached to that handle.
482 hSetBuffering :: Handle -> BufferMode -> IO ()
484 hSetBuffering handle mode =
486 BlockBuffering (Just n)
487 | n <= 0 -> fail (IOError (Just handle)
490 ("illegal buffer size " ++ showsPrec 9 n [])) -- 9 => should be parens'ified.
492 withHandle handle $ \ handle_ -> do
493 case haType__ handle_ of
494 ErrorHandle ioError -> do
495 writeHandle handle handle_
498 writeHandle handle handle_
499 ioe_closedHandle "hSetBuffering" handle
502 - we flush the old buffer regardless of whether
503 the new buffer could fit the contents of the old buffer
505 - allow a handle's buffering to change even if IO has
506 occurred (ANSI C spec. does not allow this, nor did
507 the previous implementation of IO.hSetBuffering).
508 - a non-standard extension is to allow the buffering
509 of semi-closed handles to change [sof 6/98]
511 let fo = haFO__ handle_
512 rc <- mayBlock fo (CCALL(setBuffering) fo bsize) -- ConcHask: UNSAFE, may block
515 writeHandle handle (handle_{ haBufferMode__ = mode })
517 -- Note: failure to change the buffer size will cause old buffer to be flushed.
518 writeHandle handle handle_
519 constructErrorAndFail "hSetBuffering"
525 BlockBuffering Nothing -> -2
526 BlockBuffering (Just n) -> n
529 The action @hFlush hdl@ causes any items buffered for output
530 in handle {\em hdl} to be sent immediately to the operating
534 hFlush :: Handle -> IO ()
536 wantWriteableHandle "hFlush" handle $ \ handle_ -> do
537 let fo = haFO__ handle_
538 rc <- mayBlock fo (CCALL(flushFile) fo) -- ConcHask: UNSAFE, may block
539 writeHandle handle handle_
543 constructErrorAndFail "hFlush"
548 %*********************************************************
550 \subsection[Seeking]{Repositioning Handles}
552 %*********************************************************
557 Handle -- Q: should this be a weak or strong ref. to the handle?
560 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
561 deriving (Eq, Ord, Ix, Enum, Read, Show)
564 Computation @hGetPosn hdl@ returns the current I/O
565 position of {\em hdl} as an abstract position. Computation
566 $hSetPosn p$ sets the position of {\em hdl}
567 to a previously obtained position {\em p}.
570 hGetPosn :: Handle -> IO HandlePosn
572 wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
573 posn <- CCALL(getFilePosn) (haFO__ handle_) -- ConcHask: SAFE, won't block
574 writeHandle handle handle_
576 return (HandlePosn handle posn)
578 constructErrorAndFail "hGetPosn"
580 hSetPosn :: HandlePosn -> IO ()
581 hSetPosn (HandlePosn handle posn) =
582 wantSeekableHandle "hSetPosn" handle $ \ handle_ -> do -- not as silly as it looks: the handle may have been closed in the meantime.
583 let fo = haFO__ handle_
584 rc <- mayBlock fo (CCALL(setFilePosn) fo posn) -- ConcHask: UNSAFE, may block
585 writeHandle handle handle_
589 constructErrorAndFail "hSetPosn"
592 The action @hSeek hdl mode i@ sets the position of handle
593 @hdl@ depending on @mode@. If @mode@ is
595 \item[{\bf AbsoluteSeek}] The position of @hdl@ is set to @i@.
596 \item[{\bf RelativeSeek}] The position of @hdl@ is set to offset @i@ from
597 the current position.
598 \item[{\bf SeekFromEnd}] The position of @hdl@ is set to offset @i@ from
602 Some handles may not be seekable (see @hIsSeekable@), or only support a
603 subset of the possible positioning operations (e.g. it may only be
604 possible to seek to the end of a tape, or to a positive offset from
605 the beginning or current position).
607 It is not possible to set a negative I/O position, or for a physical
608 file, an I/O position beyond the current end-of-file.
611 - when seeking using @SeekFromEnd@, positive offsets (>=0) means seeking
613 - relative seeking on buffered handles can lead to non-obvious results.
616 hSeek :: Handle -> SeekMode -> Integer -> IO ()
618 hSeek handle mode offset =
619 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
620 let fo = haFO__ handle_
621 rc <- mayBlock fo (CCALL(seekFile_int64) fo whence (primIntegerToInt64 offset)) -- ConcHask: UNSAFE, may block
623 hSeek handle mode offset@(J# _ s# d#) =
624 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
625 let fo = haFO__ handle_
626 rc <- mayBlock fo (CCALL(seekFile) fo whence (I# s#) d#) -- ConcHask: UNSAFE, may block
628 writeHandle handle handle_
632 constructErrorAndFail "hSeek"
635 whence = case mode of
641 %*********************************************************
643 \subsection[Query]{Handle Properties}
645 %*********************************************************
647 A number of operations return information about the properties of a
648 handle. Each of these operations returns $True$ if the
649 handle has the specified property, and $False$
652 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
653 {\em hdl} is not block-buffered. Otherwise it returns
654 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
655 $( Just n )$ for block-buffering of {\em n} bytes.
658 hIsOpen :: Handle -> IO Bool
660 withHandle handle $ \ handle_ -> do
661 case haType__ handle_ of
662 ErrorHandle ioError -> do
663 writeHandle handle handle_
666 writeHandle handle handle_
668 SemiClosedHandle -> do
669 writeHandle handle handle_
672 writeHandle handle handle_
675 hIsClosed :: Handle -> IO Bool
677 withHandle handle $ \ handle_ -> do
678 case haType__ handle_ of
679 ErrorHandle ioError -> do
680 writeHandle handle handle_
683 writeHandle handle handle_
686 writeHandle handle handle_
689 {- not defined, nor exported, but mentioned
690 here for documentation purposes:
692 hSemiClosed :: Handle -> IO Bool
696 return (not (ho || hc))
699 hIsReadable :: Handle -> IO Bool
701 withHandle handle $ \ handle_ -> do
702 case haType__ handle_ of
703 ErrorHandle ioError -> do
704 writeHandle handle handle_
707 writeHandle handle handle_
708 ioe_closedHandle "hIsReadable" handle
709 SemiClosedHandle -> do
710 writeHandle handle handle_
711 ioe_closedHandle "hIsReadable" handle
713 writeHandle handle handle_
714 return (isReadable htype)
716 isReadable ReadHandle = True
717 isReadable ReadWriteHandle = True
720 hIsWritable :: Handle -> IO Bool
722 withHandle handle $ \ handle_ -> do
723 case haType__ handle_ of
724 ErrorHandle ioError -> do
725 writeHandle handle handle_
728 writeHandle handle handle_
729 ioe_closedHandle "hIsWritable" handle
730 SemiClosedHandle -> do
731 writeHandle handle handle_
732 ioe_closedHandle "hIsWritable" handle
734 writeHandle handle handle_
735 return (isWritable htype)
737 isWritable AppendHandle = True
738 isWritable WriteHandle = True
739 isWritable ReadWriteHandle = True
743 #ifndef __PARALLEL_HASKELL__
744 getBMode__ :: ForeignObj -> IO (BufferMode, Int)
746 getBMode__ :: Addr -> IO (BufferMode, Int)
749 rc <- CCALL(getBufferMode) fo -- ConcHask: SAFE, won't block
751 0 -> return (NoBuffering, 0)
752 -1 -> return (LineBuffering, default_buffer_size)
753 -2 -> return (BlockBuffering Nothing, default_buffer_size)
754 -3 -> return (NoBuffering, 0) -- only happens on un-stat()able files.
755 n -> return (BlockBuffering (Just n), n)
757 default_buffer_size :: Int
758 default_buffer_size = (const_BUFSIZ - 1)
761 Querying how a handle buffers its data:
764 hGetBuffering :: Handle -> IO BufferMode
765 hGetBuffering handle =
766 withHandle handle $ \ handle_ -> do
767 case haType__ handle_ of
768 ErrorHandle ioError -> do
769 writeHandle handle handle_
772 writeHandle handle handle_
773 ioe_closedHandle "hGetBuffering" handle
776 We're being non-standard here, and allow the buffering
777 of a semi-closed handle to be queried. -- sof 6/98
779 let v = haBufferMode__ handle_
780 writeHandle handle handle_
781 return v -- could be stricter..
786 hIsSeekable :: Handle -> IO Bool
788 withHandle handle $ \ handle_ -> do
789 case haType__ handle_ of
790 ErrorHandle ioError -> do
791 writeHandle handle handle_
794 writeHandle handle handle_
795 ioe_closedHandle "hIsSeekable" handle
796 SemiClosedHandle -> do
797 writeHandle handle handle_
798 ioe_closedHandle "hIsSeekable" handle
800 writeHandle handle handle_
803 rc <- CCALL(seekFileP) (haFO__ handle_) -- ConcHask: SAFE, won't block
804 writeHandle handle handle_
808 _ -> constructErrorAndFail "hIsSeekable"
812 %*********************************************************
814 \subsection{Changing echo status}
816 %*********************************************************
818 Non-standard GHC extension is to allow the echoing status
819 of a handles connected to terminals to be reconfigured:
822 hSetEcho :: Handle -> Bool -> IO ()
823 hSetEcho handle on = do
824 isT <- hIsTerminalDevice handle
828 withHandle handle $ \ handle_ -> do
829 case haType__ handle_ of
830 ErrorHandle ioError -> do
831 writeHandle handle handle_
834 writeHandle handle handle_
835 ioe_closedHandle "hSetEcho" handle
837 rc <- CCALL(setTerminalEcho) (haFO__ handle_) (if on then 1 else 0) -- ConcHask: SAFE, won't block
838 writeHandle handle handle_
841 else constructErrorAndFail "hSetEcho"
843 hGetEcho :: Handle -> IO Bool
845 isT <- hIsTerminalDevice handle
849 withHandle handle $ \ handle_ -> do
850 case haType__ handle_ of
851 ErrorHandle ioError -> do
852 writeHandle handle handle_
855 writeHandle handle handle_
856 ioe_closedHandle "hGetEcho" handle
858 rc <- CCALL(getTerminalEcho) (haFO__ handle_) -- ConcHask: SAFE, won't block
859 writeHandle handle handle_
863 _ -> constructErrorAndFail "hSetEcho"
865 hIsTerminalDevice :: Handle -> IO Bool
866 hIsTerminalDevice handle = do
867 withHandle handle $ \ handle_ -> do
868 case haType__ handle_ of
869 ErrorHandle ioError -> do
870 writeHandle handle handle_
873 writeHandle handle handle_
874 ioe_closedHandle "hIsTerminalDevice" handle
876 rc <- CCALL(isTerminalDevice) (haFO__ handle_) -- ConcHask: SAFE, won't block
877 writeHandle handle handle_
881 _ -> constructErrorAndFail "hIsTerminalDevice"
885 hConnectTerms :: Handle -> Handle -> IO ()
886 hConnectTerms hW hR = hConnectHdl_ hW hR 1{-check if they're both coming connected to ttys-}
888 hConnectTo :: Handle -> Handle -> IO ()
889 hConnectTo hW hR = hConnectHdl_ hW hR 0{-connect regardless-}
891 hConnectHdl_ :: Handle -> Handle -> Int -> IO ()
892 hConnectHdl_ hW hR is_tty =
893 wantWriteableHandle "hConnectTo" hW $ \ hW_ -> do
894 wantReadableHandle "hConnectTo" hR $ \ hR_ -> do
895 CCALL(setConnectedTo) (haFO__ hR_) (haFO__ hW_) is_tty -- ConcHask: SAFE, won't block
901 As an extension, we also allow characters to be pushed back.
902 Like ANSI C stdio, we guarantee no more than one character of
903 pushback. (For unbuffered channels, the (default) push-back limit is
907 hUngetChar :: Handle -> Char -> IO ()
908 hUngetChar handle c =
909 wantReadableHandle "hLookAhead" handle $ \ handle_ -> do
910 rc <- CCALL(ungetChar) (haFO__ handle_) c -- ConcHask: SAFE, won't block
911 writeHandle handle handle_
913 then constructErrorAndFail "hUngetChar"
919 Hoisting files in in one go is sometimes useful, so we support
920 this as an extension:
923 -- in one go, read file into an externally allocated buffer.
924 slurpFile :: FilePath -> IO (Addr, Int)
926 handle <- openFile fname ReadMode
927 sz <- hFileSize handle
928 if sz > toInteger (maxBound::Int) then
929 fail (userError "slurpFile: file too big")
931 let sz_i = fromInteger sz
932 chunk <- CCALL(allocMemory__) (sz_i::Int)
936 constructErrorAndFail "slurpFile"
938 withHandle handle $ \ handle_ -> do
939 let fo = haFO__ handle_
940 rc <- mayBlock fo (CCALL(readChunk) fo chunk sz_i) -- ConcHask: UNSAFE, may block.
941 writeHandle handle handle_
944 then constructErrorAndFail "slurpFile"
945 else return (chunk, rc)
947 #ifndef __HUGS__ /* Hugs' Prelude doesn't need this */
948 hFillBufBA :: Handle -> ByteArray Int -> Int -> IO Int
949 hFillBufBA handle buf sz
950 | sz <= 0 = fail (IOError (Just handle)
953 ("illegal buffer size " ++ showsPrec 9 sz [])) -- 9 => should be parens'ified.
955 wantReadableHandle "hFillBufBA" handle $ \ handle_ -> do
956 let fo = haFO__ handle_
958 rc <- mayBlock fo (CCALL(readChunkBA) fo buf sz) -- ConcHask: UNSAFE, may block.
960 rc <- mayBlock fo (CCALL(readChunk) fo buf sz) -- ConcHask: UNSAFE, may block.
962 writeHandle handle handle_
965 else constructErrorAndFail "hFillBufBA"
968 hFillBuf :: Handle -> Addr -> Int -> IO Int
969 hFillBuf handle buf sz
970 | sz <= 0 = fail (IOError (Just handle)
973 ("illegal buffer size " ++ showsPrec 9 sz [])) -- 9 => should be parens'ified.
975 wantReadableHandle "hFillBuf" handle $ \ handle_ -> do
976 let fo = haFO__ handle_
977 rc <- mayBlock fo (CCALL(readChunk) fo buf sz) -- ConcHask: UNSAFE, may block.
978 writeHandle handle handle_
981 else constructErrorAndFail "hFillBuf"
985 The @hPutBuf hdl buf len@ action writes an already packed sequence of
986 bytes to the file/channel managed by @hdl@ - non-standard.
989 hPutBuf :: Handle -> Addr -> Int -> IO ()
990 hPutBuf handle buf len =
991 wantWriteableHandle "hPutBuf" handle $ \ handle_ -> do
992 let fo = haFO__ handle_
993 rc <- mayBlock fo (CCALL(writeBuf) fo buf len) -- ConcHask: UNSAFE, may block.
994 writeHandle handle handle_
997 else constructErrorAndFail "hPutBuf"
999 #ifndef __HUGS__ /* Another one Hugs doesn't provide */
1000 hPutBufBA :: Handle -> ByteArray Int -> Int -> IO ()
1001 hPutBufBA handle buf len =
1002 wantWriteableHandle "hPutBufBA" handle $ \ handle_ -> do
1003 let fo = haFO__ handle_
1004 rc <- mayBlock fo (CCALL(writeBufBA) fo buf len) -- ConcHask: UNSAFE, may block.
1005 writeHandle handle handle_
1008 else constructErrorAndFail "hPutBuf"
1012 Sometimes it's useful to get at the file descriptor that
1013 the Handle contains..
1016 getHandleFd :: Handle -> IO Int
1017 getHandleFd handle = do
1018 withHandle handle $ \ handle_ -> do
1019 case (haType__ handle_) of
1020 ErrorHandle ioError -> do
1021 writeHandle handle handle_
1024 writeHandle handle handle_
1025 ioe_closedHandle "getHandleFd" handle
1027 fd <- CCALL(getFileFd) (haFO__ handle_)
1028 writeHandle handle handle_
1033 %*********************************************************
1035 \subsection{Miscellaneous}
1037 %*********************************************************
1039 These three functions are meant to get things out of @IOErrors@.
1044 ioeGetFileName :: IOError -> Maybe FilePath
1045 ioeGetErrorString :: IOError -> String
1046 ioeGetHandle :: IOError -> Maybe Handle
1048 ioeGetHandle (IOError h _ _ _) = h
1049 ioeGetErrorString (IOError _ iot _ str) =
1051 EOF -> "end of file"
1054 ioeGetFileName (IOError _ _ _ str) =
1055 case span (/=':') str of
1061 A number of operations want to get at a readable or writeable handle, and fail
1065 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1066 wantReadableHandle fun handle act =
1067 withHandle handle $ \ handle_ -> do
1068 case haType__ handle_ of
1069 ErrorHandle ioError -> do
1070 writeHandle handle handle_
1073 writeHandle handle handle_
1074 ioe_closedHandle fun handle
1075 SemiClosedHandle -> do
1076 writeHandle handle handle_
1077 ioe_closedHandle fun handle
1079 writeHandle handle handle_
1080 fail not_readable_error
1082 writeHandle handle handle_
1083 fail not_readable_error
1084 other -> act handle_
1086 not_readable_error =
1087 IOError (Just handle) IllegalOperation fun
1088 ("handle is not open for reading")
1090 wantWriteableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1091 wantWriteableHandle fun handle act =
1092 withHandle handle $ \ handle_ -> do
1093 case haType__ handle_ of
1094 ErrorHandle ioError -> do
1095 writeHandle handle handle_
1098 writeHandle handle handle_
1099 ioe_closedHandle fun handle
1100 SemiClosedHandle -> do
1101 writeHandle handle handle_
1102 ioe_closedHandle fun handle
1104 writeHandle handle handle_
1105 fail not_writeable_error
1106 other -> act handle_
1108 not_writeable_error =
1109 IOError (Just handle) IllegalOperation fun
1110 ("handle is not open for writing")
1112 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
1113 wantSeekableHandle fun handle act =
1114 withHandle handle $ \ handle_ -> do
1115 case haType__ handle_ of
1116 ErrorHandle ioError -> do
1117 writeHandle handle handle_
1120 writeHandle handle handle_
1121 ioe_closedHandle fun handle
1122 SemiClosedHandle -> do
1123 writeHandle handle handle_
1124 ioe_closedHandle fun handle
1126 writeHandle handle handle_
1127 fail not_seekable_error
1130 not_seekable_error =
1131 IOError (Just handle)
1132 IllegalOperation fun
1133 ("handle is not seekable")
1137 Internal function for creating an @IOError@ representing the
1138 access to a closed file.
1141 ioe_closedHandle :: String -> Handle -> IO a
1142 ioe_closedHandle fun h = fail (IOError (Just h) IllegalOperation fun "handle is closed")
1145 Internal helper functions for Concurrent Haskell implementation
1149 #ifndef __PARALLEL_HASKELL__
1150 mayBlock :: ForeignObj -> IO Int -> IO Int
1152 mayBlock :: Addr -> IO Int -> IO Int
1155 #ifndef notyet /*__CONCURRENT_HASKELL__*/
1156 mayBlock _ act = act
1158 mayBlock fo act = do
1161 -5 -> do -- (possibly blocking) read
1162 fd <- CCALL(getFileFd) fo
1164 CCALL(clearNonBlockingIOFlag__) fo -- force read to happen this time.
1165 mayBlock fo act -- input available, re-try
1166 -6 -> do -- (possibly blocking) write
1167 fd <- CCALL(getFileFd) fo
1169 CCALL(clearNonBlockingIOFlag__) fo -- force write to happen this time.
1170 mayBlock fo act -- output possible
1171 -7 -> do -- (possibly blocking) write on connected handle
1172 fd <- CCALL(getConnFileFd) fo
1174 CCALL(clearConnNonBlockingIOFlag__) fo -- force write to happen this time.
1175 mayBlock fo act -- output possible
1177 CCALL(setNonBlockingIOFlag__) fo -- reset file object.
1178 CCALL(setConnNonBlockingIOFlag__) fo -- reset (connected) file object.
1184 threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
1186 -- Hugs does actually have the primops needed to implement these
1187 -- but, like GHC, the primops don't actually do anything...
1188 threadDelay _ = return ()
1189 threadWaitRead _ = return ()
1190 threadWaitWrite _ = return ()
1199 type Exclusive = Int -- really Bool
1202 type OpenStdFlags = Int
1203 type OpenFlags = Int
1204 type Readable = Int -- really Bool
1205 type Flush = Int -- really Bool
1206 type RC = Int -- standard return code
1208 type IOFileAddr = Addr -- as returned from functions
1209 type CString = PrimByteArray
1210 type Bytes = PrimMutableByteArray RealWorld
1212 #ifndef __PARALLEL_HASKELL__
1213 type FILE_OBJ = ForeignObj -- as passed into functions
1215 type FILE_OBJ = Addr
1218 foreign import stdcall "libHS_cbits.so" "setBuf" prim_setBuf :: FILE_OBJ -> Addr -> Int -> IO ()
1219 foreign import stdcall "libHS_cbits.so" "getBufSize" prim_getBufSize :: FILE_OBJ -> IO Int
1220 foreign import stdcall "libHS_cbits.so" "inputReady" prim_inputReady :: FILE_OBJ -> Int -> IO RC
1221 foreign import stdcall "libHS_cbits.so" "fileGetc" prim_fileGetc :: FILE_OBJ -> IO Int
1222 foreign import stdcall "libHS_cbits.so" "fileLookAhead" prim_fileLookAhead :: FILE_OBJ -> IO Int
1223 foreign import stdcall "libHS_cbits.so" "readBlock" prim_readBlock :: FILE_OBJ -> IO Int
1224 foreign import stdcall "libHS_cbits.so" "readLine" prim_readLine :: FILE_OBJ -> IO Int
1225 foreign import stdcall "libHS_cbits.so" "readChar" prim_readChar :: FILE_OBJ -> IO Int
1226 foreign import stdcall "libHS_cbits.so" "writeFileObject" prim_writeFileObject :: FILE_OBJ -> Int -> IO RC
1227 foreign import stdcall "libHS_cbits.so" "filePutc" prim_filePutc :: FILE_OBJ -> Char -> IO RC
1228 foreign import stdcall "libHS_cbits.so" "getBufStart" prim_getBufStart :: FILE_OBJ -> Int -> IO Addr
1229 foreign import stdcall "libHS_cbits.so" "getWriteableBuf" prim_getWriteableBuf :: FILE_OBJ -> IO Addr
1230 foreign import stdcall "libHS_cbits.so" "getBufWPtr" prim_getBufWPtr :: FILE_OBJ -> IO Int
1231 foreign import stdcall "libHS_cbits.so" "setBufWPtr" prim_setBufWPtr :: FILE_OBJ -> Int -> IO ()
1232 foreign import stdcall "libHS_cbits.so" "closeFile" prim_closeFile :: FILE_OBJ -> Flush -> IO RC
1233 foreign import stdcall "libHS_cbits.so" "fileEOF" prim_fileEOF :: FILE_OBJ -> IO RC
1234 foreign import stdcall "libHS_cbits.so" "setBuffering" prim_setBuffering :: FILE_OBJ -> Int -> IO RC
1235 foreign import stdcall "libHS_cbits.so" "flushFile" prim_flushFile :: FILE_OBJ -> IO RC
1236 foreign import stdcall "libHS_cbits.so" "getBufferMode" prim_getBufferMode :: FILE_OBJ -> IO RC
1237 foreign import stdcall "libHS_cbits.so" "seekFile_int64" prim_seekFile_int64 :: FILE_OBJ -> Int -> Int64 -> IO RC
1238 foreign import stdcall "libHS_cbits.so" "seekFileP" prim_seekFileP :: FILE_OBJ -> IO RC
1239 foreign import stdcall "libHS_cbits.so" "setTerminalEcho" prim_setTerminalEcho :: FILE_OBJ -> Int -> IO RC
1240 foreign import stdcall "libHS_cbits.so" "getTerminalEcho" prim_getTerminalEcho :: FILE_OBJ -> IO RC
1241 foreign import stdcall "libHS_cbits.so" "isTerminalDevice" prim_isTerminalDevice :: FILE_OBJ -> IO RC
1242 foreign import stdcall "libHS_cbits.so" "setConnectedTo" prim_setConnectedTo :: FILE_OBJ -> FILE_OBJ -> Int -> IO ()
1243 foreign import stdcall "libHS_cbits.so" "ungetChar" prim_ungetChar :: FILE_OBJ -> Char -> IO RC
1244 foreign import stdcall "libHS_cbits.so" "readChunk" prim_readChunk :: FILE_OBJ -> Addr -> Int -> IO RC
1245 foreign import stdcall "libHS_cbits.so" "writeBuf" prim_writeBuf :: FILE_OBJ -> Addr -> Int -> IO RC
1246 foreign import stdcall "libHS_cbits.so" "getFileFd" prim_getFileFd :: FILE_OBJ -> IO FD
1247 foreign import stdcall "libHS_cbits.so" "fileSize_int64" prim_fileSize_int64 :: FILE_OBJ -> Bytes -> IO RC
1248 foreign import stdcall "libHS_cbits.so" "getFilePosn" prim_getFilePosn :: FILE_OBJ -> IO Int
1249 foreign import stdcall "libHS_cbits.so" "setFilePosn" prim_setFilePosn :: FILE_OBJ -> Int -> IO Int
1250 foreign import stdcall "libHS_cbits.so" "getConnFileFd" prim_getConnFileFd :: FILE_OBJ -> IO FD
1251 foreign import stdcall "libHS_cbits.so" "allocMemory__" prim_allocMemory__ :: Int -> IO Addr
1252 foreign import stdcall "libHS_cbits.so" "getLock" prim_getLock :: FD -> Exclusive -> IO RC
1253 foreign import stdcall "libHS_cbits.so" "openStdFile" prim_openStdFile :: FD -> OpenStdFlags -> Readable -> IO IOFileAddr
1254 foreign import stdcall "libHS_cbits.so" "openFile" prim_openFile :: CString -> How -> Binary -> OpenFlags -> IO IOFileAddr
1255 foreign import stdcall "libHS_cbits.so" "freeFileObject" prim_freeFileObject :: FILE_OBJ -> IO ()
1256 foreign import stdcall "libHS_cbits.so" "freeStdFileObject" prim_freeStdFileObject :: FILE_OBJ -> IO ()
1257 foreign import stdcall "libHS_cbits.so" "const_BUFSIZ" const_BUFSIZ :: Int
1259 foreign import stdcall "libHS_cbits.so" "setConnNonBlockingIOFlag__" prim_setConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
1260 foreign import stdcall "libHS_cbits.so" "clearConnNonBlockingIOFlag__" prim_clearConnNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
1261 foreign import stdcall "libHS_cbits.so" "setNonBlockingIOFlag__" prim_setNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
1262 foreign import stdcall "libHS_cbits.so" "clearNonBlockingIOFlag__" prim_clearNonBlockingIOFlag__ :: FILE_OBJ -> IO ()
1264 foreign import stdcall "libHS_cbits.so" "getErrStr__" prim_getErrStr__ :: IO Addr
1265 foreign import stdcall "libHS_cbits.so" "getErrNo__" prim_getErrNo__ :: IO Int
1266 foreign import stdcall "libHS_cbits.so" "getErrType__" prim_getErrType__ :: IO Int