2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[IOHandle]{Module @IOHandle@}
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" #-}
20 import ArrBase ( ByteArray(..) )
21 import PrelRead ( Read )
27 import Foreign ( ForeignObj, Addr, makeForeignObj, writeForeignObj )
28 import PrelList (span)
29 #if defined(__CONCURRENT_HASKELL__)
35 %*********************************************************
37 \subsection{Types @FilePath@, @Handle@, @Handle__@}
39 %*********************************************************
41 The @Handle@ and @Handle__@ types are defined in @IOBase@.
44 type FilePath = String
46 {-# INLINE newHandle #-}
47 {-# INLINE readHandle #-}
48 {-# INLINE writeHandle #-}
49 newHandle :: Handle__ -> IO Handle
50 readHandle :: Handle -> IO Handle__
51 writeHandle :: Handle -> Handle__ -> IO ()
53 #if defined(__CONCURRENT_HASKELL__)
58 newHandle v = stToIO (newVar v)
59 readHandle h = stToIO (readVar h)
60 writeHandle h v = stToIO (writeVar h v)
65 %*********************************************************
67 \subsection{Functions}
69 %*********************************************************
73 filePtr :: Handle__ -> ForeignObj
75 filePtr :: Handle__ -> Addr
77 filePtr (SemiClosedHandle fp _) = fp
78 filePtr (ReadHandle fp _ _) = fp
79 filePtr (WriteHandle fp _ _) = fp
80 filePtr (AppendHandle fp _ _) = fp
81 filePtr (ReadWriteHandle fp _ _) = fp
83 bufferMode :: Handle__ -> Maybe BufferMode
84 bufferMode (ReadHandle _ m _) = m
85 bufferMode (WriteHandle _ m _) = m
86 bufferMode (AppendHandle _ m _) = m
87 bufferMode (ReadWriteHandle _ m _) = m
89 markHandle :: Handle__ -> Handle__
90 markHandle h@(ReadHandle fp m b)
92 | otherwise = ReadHandle fp m True
93 markHandle h@(WriteHandle fp m b)
95 | otherwise = WriteHandle fp m True
96 markHandle h@(AppendHandle fp m b)
98 | otherwise = AppendHandle fp m True
99 markHandle h@(ReadWriteHandle fp m b)
101 | otherwise = ReadWriteHandle fp m True
104 -------------------------------------------
106 %*********************************************************
108 \subsection[StdHandles]{Standard handles}
110 %*********************************************************
112 Three handles are allocated during program initialisation. The first
113 two manage input or output from the Haskell program's standard input
114 or output channel respectively. The third manages output to the
115 standard error channel. These handles are initially open.
118 stdin, stdout, stderr :: Handle
120 stdin = unsafePerformPrimIO (
121 _ccall_ getLock (``stdin''::Addr) 0 >>= \ rc ->
123 0 -> new_handle ClosedHandle
126 makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
127 new_handle (ReadHandle fp Nothing False)
129 new_handle (ReadHandle ``stdin'' Nothing False)
131 _ -> constructError "stdin" >>= \ ioError ->
132 new_handle (ErrorHandle ioError)
137 new_handle x = ioToST (newHandle x)
139 stdout = unsafePerformPrimIO (
140 _ccall_ getLock (``stdout''::Addr) 1 >>= \ rc ->
142 0 -> new_handle ClosedHandle
145 makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
146 new_handle (WriteHandle fp Nothing False)
148 new_handle (WriteHandle ``stdout'' Nothing False)
150 _ -> constructError "stdout" >>= \ ioError ->
151 new_handle (ErrorHandle ioError)
156 new_handle x = ioToST (newHandle x)
158 stderr = unsafePerformPrimIO (
159 _ccall_ getLock (``stderr''::Addr) 1 >>= \ rc ->
161 0 -> new_handle ClosedHandle
164 makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
165 new_handle (WriteHandle fp (Just NoBuffering) False)
167 new_handle (WriteHandle ``stderr'' (Just NoBuffering) False)
169 _ -> constructError "stderr" >>= \ ioError ->
170 new_handle (ErrorHandle ioError)
175 new_handle x = ioToST (newHandle x)
178 %*********************************************************
180 \subsection[OpeningClosing]{Opening and Closing Files}
182 %*********************************************************
185 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
186 deriving (Eq, Ord, Ix, Enum, Read, Show)
188 openFile :: FilePath -> IOMode -> IO Handle
191 stToIO (_ccall_ openFile f m') >>= \ ptr ->
192 if ptr /= ``NULL'' then
194 makeForeignObj ptr ((``&freeFile'')::Addr) `thenIO_Prim` \ fp ->
195 newHandle (htype fp Nothing False)
197 newHandle (htype ptr Nothing False)
200 stToIO (constructError "openFile") >>= \ ioError@(IOError hn iot msg) ->
202 improved_error -- a HACK, I guess
204 AlreadyExists -> IOError hn AlreadyExists (msg ++ ": " ++ f)
205 NoSuchThing -> IOError hn NoSuchThing (msg ++ ": " ++ f)
206 PermissionDenied -> IOError hn PermissionDenied (msg ++ ": " ++ f)
215 ReadWriteMode -> "r+"
218 ReadMode -> ReadHandle
219 WriteMode -> WriteHandle
220 AppendMode -> AppendHandle
221 ReadWriteMode -> ReadWriteHandle
224 Computation $openFile file mode$ allocates and returns a new, open
225 handle to manage the file {\em file}. It manages input if {\em mode}
226 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
227 and both input and output if mode is $ReadWriteMode$.
229 If the file does not exist and it is opened for output, it should be
230 created as a new file. If {\em mode} is $WriteMode$ and the file
231 already exists, then it should be truncated to zero length. The
232 handle is positioned at the end of the file if {\em mode} is
233 $AppendMode$, and otherwise at the beginning (in which case its
234 internal position is 0).
236 Implementations should enforce, locally to the Haskell process,
237 multiple-reader single-writer locking on files, which is to say that
238 there may either be many handles on the same file which manage input,
239 or just one handle on the file which manages output. If any open or
240 semi-closed handle is managing a file for output, no new handle can be
241 allocated for that file. If any open or semi-closed handle is
242 managing a file for input, new handles can only be allocated if they
243 do not manage output.
245 Two files are the same if they have the same absolute name. An
246 implementation is free to impose stricter conditions.
249 hClose :: Handle -> IO ()
252 readHandle handle >>= \ htype ->
254 ErrorHandle ioError ->
255 writeHandle handle htype >>
258 writeHandle handle htype >>
259 ioe_closedHandle handle
260 SemiClosedHandle fp (buf,_) ->
261 (if buf /= ``NULL'' then
264 returnPrimIO ()) `thenIO_Prim` \ () ->
265 _casm_ `` %r = (char *)%0; '' fp `thenIO_Prim` \ fp_a ->
266 if fp_a /= (``NULL''::Addr) then -- Under what condition can this be NULL?
267 _ccall_ closeFile fp `thenIO_Prim` \ rc ->
268 {- We explicitly close a file object so that we can be told
269 if there were any errors. Note that after @hClose@
270 has been performed, the ForeignObj embedded in the Handle
271 is still lying around in the heap, so care is taken
272 to avoid closing the file object when the ForeignObj
276 -- Mark the foreign object data value as gone to the finaliser (freeFile())
277 writeForeignObj fp ``NULL'' `thenIO_Prim` \ () ->
279 writeHandle handle ClosedHandle
281 writeHandle handle htype >>
282 constructErrorAndFail "hClose"
285 writeHandle handle htype
287 let fp = filePtr other in
288 _ccall_ closeFile fp `thenIO_Prim` \ rc ->
291 -- Mark the foreign object data
292 writeForeignObj fp ``NULL'' `thenIO_Prim` \ () ->
294 writeHandle handle ClosedHandle
296 writeHandle handle htype >>
297 constructErrorAndFail "hClose"
300 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
301 computation finishes, any items buffered for output and not already
302 sent to the operating system are flushed as for $flush$.
304 %*********************************************************
306 \subsection[EOF]{Detecting the End of Input}
308 %*********************************************************
311 For a handle {\em hdl} which attached to a physical file, $hFileSize
312 hdl$ returns the size of {\em hdl} in terms of the number of items
313 which can be read from {\em hdl}.
316 hFileSize :: Handle -> IO Integer
318 readHandle handle >>= \ htype ->
320 ErrorHandle ioError ->
321 writeHandle handle htype >>
324 writeHandle handle htype >>
325 ioe_closedHandle handle
326 SemiClosedHandle _ _ ->
327 writeHandle handle htype >>
328 ioe_closedHandle handle
330 -- HACK! We build a unique MP_INT of the right shape to hold
331 -- a single unsigned word, and we let the C routine change the data bits
332 _casm_ ``%r = 1;'' `thenIO_Prim` \ (I# hack#) ->
333 case int2Integer# hack# of
334 result@(J# _ _ d#) ->
336 bogus_bounds = (error "fileSize"::(Int,Int))
338 _ccall_ fileSize (filePtr other) (ByteArray bogus_bounds d#)
339 `thenIO_Prim` \ rc ->
340 writeHandle handle htype >>
344 constructErrorAndFail "hFileSize"
347 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
348 $True$ if no further input can be taken from {\em hdl} or for a
349 physical file, if the current I/O position is equal to the length of
350 the file. Otherwise, it returns $False$.
353 hIsEOF :: Handle -> IO Bool
355 readHandle handle >>= \ htype ->
357 ErrorHandle ioError ->
358 writeHandle handle htype >>
361 writeHandle handle htype >>
362 ioe_closedHandle handle
363 SemiClosedHandle _ _ ->
364 writeHandle handle htype >>
365 ioe_closedHandle handle
367 writeHandle handle htype >>
368 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
369 AppendHandle _ _ _ ->
370 writeHandle handle htype >>
371 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
373 _ccall_ fileEOF (filePtr other) `thenIO_Prim` \ rc ->
374 writeHandle handle (markHandle htype) >>
378 _ -> constructErrorAndFail "hIsEOF"
384 %*********************************************************
386 \subsection[Buffering]{Buffering Operations}
388 %*********************************************************
390 Three kinds of buffering are supported: line-buffering,
391 block-buffering or no-buffering. See @IOBase@ for definition
392 and further explanation of what the type represent.
394 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
395 handle {\em hdl} on subsequent reads and writes.
399 If {\em mode} is @LineBuffering@, line-buffering should be
402 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
403 should be enabled if possible. The size of the buffer is {\em n} items
404 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
406 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
409 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
410 to @NoBuffering@, then any items in the output buffer are written to
411 the device, and any items in the input buffer are discarded. The
412 default buffering mode when a handle is opened is
413 implementation-dependent and may depend on the object which is
414 attached to that handle.
417 hSetBuffering :: Handle -> BufferMode -> IO ()
419 hSetBuffering handle mode =
421 (BlockBuffering (Just n))
422 | n <= 0 -> fail (IOError (Just handle) InvalidArgument "illegal buffer size")
424 readHandle handle >>= \ htype ->
425 if isMarked htype then
426 writeHandle handle htype >>
427 fail (IOError (Just handle)
429 "can't set buffering for a dirty handle")
432 ErrorHandle ioError ->
433 writeHandle handle htype >>
436 writeHandle handle htype >>
437 ioe_closedHandle handle
438 SemiClosedHandle _ _ ->
439 writeHandle handle htype >>
440 ioe_closedHandle handle
442 _ccall_ setBuffering (filePtr other) bsize
443 `thenIO_Prim` \ rc ->
445 writeHandle handle ((hcon other) (filePtr other) (Just mode) True)
449 writeHandle handle htype >>
450 constructErrorAndFail "hSetBuffering"
453 isMarked :: Handle__ -> Bool
454 isMarked (ReadHandle fp m b) = b
455 isMarked (WriteHandle fp m b) = b
456 isMarked (AppendHandle fp m b) = b
457 isMarked (ReadWriteHandle fp m b) = b
463 BlockBuffering Nothing -> -2
464 BlockBuffering (Just n) -> n
467 hcon :: Handle__ -> (ForeignObj -> (Maybe BufferMode) -> Bool -> Handle__)
469 hcon :: Handle__ -> (Addr -> (Maybe BufferMode) -> Bool -> Handle__)
471 hcon (ReadHandle _ _ _) = ReadHandle
472 hcon (WriteHandle _ _ _) = WriteHandle
473 hcon (AppendHandle _ _ _) = AppendHandle
474 hcon (ReadWriteHandle _ _ _) = ReadWriteHandle
477 Computation $flush hdl$ causes any items buffered for output in handle
478 {\em hdl} to be sent immediately to the operating system.
481 hFlush :: Handle -> IO ()
483 readHandle handle >>= \ htype ->
485 ErrorHandle ioError ->
486 writeHandle handle htype >>
489 writeHandle handle htype >>
490 ioe_closedHandle handle
491 SemiClosedHandle _ _ ->
492 writeHandle handle htype >>
493 ioe_closedHandle handle
495 _ccall_ flushFile (filePtr other) `thenIO_Prim` \ rc ->
496 writeHandle handle (markHandle htype) >>
500 constructErrorAndFail "hFlush"
504 %*********************************************************
506 \subsection[Seeking]{Repositioning Handles}
508 %*********************************************************
511 data HandlePosn = HandlePosn Handle Int
513 instance Eq HandlePosn{-partain-}
515 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
516 deriving (Eq, Ord, Ix, Enum, Read, Show)
519 Computation $hGetPosn hdl$ returns the current I/O
520 position of {\em hdl} as an abstract position. Computation
521 $hSetPosn p$ sets the position of {\em hdl}
522 to a previously obtained position {\em p}.
525 hGetPosn :: Handle -> IO HandlePosn
527 readHandle handle >>= \ htype ->
529 ErrorHandle ioError ->
530 writeHandle handle htype >>
533 writeHandle handle htype >>
534 ioe_closedHandle handle
535 SemiClosedHandle _ _ ->
536 writeHandle handle htype >>
537 ioe_closedHandle handle
539 _ccall_ getFilePosn (filePtr other) `thenIO_Prim` \ posn ->
540 writeHandle handle htype >>
542 return (HandlePosn handle posn)
544 constructErrorAndFail "hGetPosn"
546 hSetPosn :: HandlePosn -> IO ()
547 hSetPosn (HandlePosn handle posn) =
548 readHandle handle >>= \ htype ->
550 ErrorHandle ioError ->
551 writeHandle handle htype >>
554 writeHandle handle htype >>
555 ioe_closedHandle handle
556 SemiClosedHandle _ _ ->
557 writeHandle handle htype >>
558 ioe_closedHandle handle
559 AppendHandle _ _ _ ->
560 writeHandle handle htype >>
561 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
563 _ccall_ setFilePosn (filePtr other) posn `thenIO_Prim` \ rc ->
564 writeHandle handle (markHandle htype) >>
568 constructErrorAndFail "hSetPosn"
571 Computation $hSeek hdl mode i$ sets the position of handle
572 {\em hdl} depending on $mode$. If {\em mode} is
574 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
575 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
576 the current position.
577 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
579 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
580 the beginning of the file.
583 Some handles may not be seekable $hIsSeekable$, or only support a
584 subset of the possible positioning operations (e.g. it may only be
585 possible to seek to the end of a tape, or to a positive offset from
586 the beginning or current position).
588 It is not possible to set a negative I/O position, or for a physical
589 file, an I/O position beyond the current end-of-file.
592 hSeek :: Handle -> SeekMode -> Integer -> IO ()
593 hSeek handle mode offset@(J# _ s# d#) =
594 readHandle handle >>= \ htype ->
596 ErrorHandle ioError ->
597 writeHandle handle htype >>
600 writeHandle handle htype >>
601 ioe_closedHandle handle
602 SemiClosedHandle _ _ ->
603 writeHandle handle htype >>
604 ioe_closedHandle handle
605 AppendHandle _ _ _ ->
606 writeHandle handle htype >>
607 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
609 _ccall_ seekFile (filePtr other) whence (I# s#) (ByteArray (0,0) d#)
610 `thenIO_Prim` \ rc ->
611 writeHandle handle (markHandle htype) >>
615 constructErrorAndFail "hSeek"
618 whence = case mode of
619 AbsoluteSeek -> ``SEEK_SET''
620 RelativeSeek -> ``SEEK_CUR''
621 SeekFromEnd -> ``SEEK_END''
624 %*********************************************************
626 \subsection[Query]{Handle Properties}
628 %*********************************************************
630 A number of operations return information about the properties of a
631 handle. Each of these operations returns $True$ if the
632 handle has the specified property, and $False$
635 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
636 {\em hdl} is not block-buffered. Otherwise it returns
637 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
638 $( Just n )$ for block-buffering of {\em n} bytes.
641 hIsOpen :: Handle -> IO Bool
643 readHandle handle >>= \ htype ->
645 ErrorHandle ioError ->
646 writeHandle handle htype >>
649 writeHandle handle htype >>
651 SemiClosedHandle _ _ ->
652 writeHandle handle htype >>
655 writeHandle handle htype >>
658 hIsClosed :: Handle -> IO Bool
660 readHandle handle >>= \ htype ->
662 ErrorHandle ioError ->
663 writeHandle handle htype >>
666 writeHandle handle htype >>
669 writeHandle handle htype >>
672 hIsReadable :: Handle -> IO Bool
674 readHandle handle >>= \ htype ->
676 ErrorHandle ioError ->
677 writeHandle handle htype >>
680 writeHandle handle htype >>
681 ioe_closedHandle handle
682 SemiClosedHandle _ _ ->
683 writeHandle handle htype >>
684 ioe_closedHandle handle
686 writeHandle handle htype >>
687 return (isReadable other)
689 isReadable (ReadHandle _ _ _) = True
690 isReadable (ReadWriteHandle _ _ _) = True
693 hIsWritable :: Handle -> IO Bool
695 readHandle handle >>= \ htype ->
697 ErrorHandle ioError ->
698 writeHandle handle htype >>
701 writeHandle handle htype >>
702 ioe_closedHandle handle
703 SemiClosedHandle _ _ ->
704 writeHandle handle htype >>
705 ioe_closedHandle handle
707 writeHandle handle htype >>
708 return (isWritable other)
710 isWritable (AppendHandle _ _ _) = True
711 isWritable (WriteHandle _ _ _) = True
712 isWritable (ReadWriteHandle _ _ _) = True
715 getBufferMode :: Handle__ -> PrimIO Handle__
716 getBufferMode htype =
717 case bufferMode htype of
718 Just x -> returnPrimIO htype
720 _ccall_ getBufferMode (filePtr htype) `thenPrimIO` \ rc ->
724 0 -> Just NoBuffering
725 -1 -> Just LineBuffering
726 -2 -> Just (BlockBuffering Nothing)
728 n -> Just (BlockBuffering (Just n))
730 returnPrimIO (case htype of
731 ReadHandle fp _ b -> ReadHandle fp mode b
732 WriteHandle fp _ b -> WriteHandle fp mode b
733 AppendHandle fp _ b -> AppendHandle fp mode b
734 ReadWriteHandle fp _ b -> ReadWriteHandle fp mode b)
736 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
737 hIsBlockBuffered handle =
738 readHandle handle >>= \ htype ->
740 ErrorHandle ioError ->
741 writeHandle handle htype >>
744 writeHandle handle htype >>
745 ioe_closedHandle handle
746 SemiClosedHandle _ _ ->
747 writeHandle handle htype >>
748 ioe_closedHandle handle
750 getBufferMode other `thenIO_Prim` \ other ->
751 case bufferMode other of
752 Just (BlockBuffering size) ->
753 writeHandle handle other >>
756 writeHandle handle other >>
757 return (False, Nothing)
759 constructErrorAndFail "hIsBlockBuffered"
761 hIsLineBuffered :: Handle -> IO Bool
762 hIsLineBuffered handle =
763 readHandle handle >>= \ htype ->
765 ErrorHandle ioError ->
766 writeHandle handle htype >>
769 writeHandle handle htype >>
770 ioe_closedHandle handle
771 SemiClosedHandle _ _ ->
772 writeHandle handle htype >>
773 ioe_closedHandle handle
775 getBufferMode other `thenIO_Prim` \ other ->
776 case bufferMode other of
777 Just LineBuffering ->
778 writeHandle handle other >>
781 writeHandle handle other >>
784 constructErrorAndFail "hIsLineBuffered"
786 hIsNotBuffered :: Handle -> IO Bool
787 hIsNotBuffered handle =
788 readHandle handle >>= \ htype ->
790 ErrorHandle ioError ->
791 writeHandle handle htype >>
794 writeHandle handle htype >>
795 ioe_closedHandle handle
796 SemiClosedHandle _ _ ->
797 writeHandle handle htype >>
798 ioe_closedHandle handle
800 getBufferMode other `thenIO_Prim` \ other ->
801 case bufferMode other of
803 writeHandle handle other >>
806 writeHandle handle other >>
809 constructErrorAndFail "hIsNotBuffered"
811 hGetBuffering :: Handle -> IO BufferMode
812 hGetBuffering handle =
813 readHandle handle >>= \ htype ->
815 ErrorHandle ioError ->
816 writeHandle handle htype >>
819 writeHandle handle htype >>
820 ioe_closedHandle handle
821 SemiClosedHandle _ _ ->
822 writeHandle handle htype >>
823 ioe_closedHandle handle
825 getBufferMode other `thenIO_Prim` \ other ->
826 case bufferMode other of
828 writeHandle handle other >>
831 constructErrorAndFail "hGetBuffering"
833 hIsSeekable :: Handle -> IO Bool
835 readHandle handle >>= \ htype ->
837 ErrorHandle ioError ->
838 writeHandle handle htype >>
841 writeHandle handle htype >>
842 ioe_closedHandle handle
843 SemiClosedHandle _ _ ->
844 writeHandle handle htype >>
845 ioe_closedHandle handle
846 AppendHandle _ _ _ ->
847 writeHandle handle htype >>
850 _ccall_ seekFileP (filePtr other) `thenIO_Prim` \ rc ->
851 writeHandle handle htype >>
855 _ -> constructErrorAndFail "hIsSeekable"
859 %*********************************************************
861 \subsection{Miscellaneous}
863 %*********************************************************
865 These two functions are meant to get things out of @IOErrors@. They don't!
868 ioeGetFileName :: IOError -> Maybe FilePath
869 ioeGetErrorString :: IOError -> String
870 ioeGetHandle :: IOError -> Maybe Handle
872 ioeGetHandle (IOError h _ _) = h
873 ioeGetErrorString (IOError _ iot str) =
878 ioeGetFileName (IOError _ _ str) =
879 case span (/=':') str of
885 Internal function for creating an @IOError@ representing the
886 access of a closed file.
890 ioe_closedHandle :: Handle -> IO a
891 ioe_closedHandle h = fail (IOError (Just h) IllegalOperation "handle is closed")