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.
13 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
19 import ArrBase ( ByteArray(..) )
20 import PrelRead ( Read )
26 import Foreign ( makeForeignObj )
27 import PrelList (span)
28 #if defined(__CONCURRENT_HASKELL__)
34 %*********************************************************
36 \subsection{Types @FilePath@, @Handle@, @Handle__@}
38 %*********************************************************
40 The @Handle@ and @Handle__@ types are defined in @IOBase@.
43 type FilePath = String
45 {-# INLINE newHandle #-}
46 {-# INLINE readHandle #-}
47 {-# INLINE writeHandle #-}
48 newHandle :: Handle__ -> IO Handle
49 readHandle :: Handle -> IO Handle__
50 writeHandle :: Handle -> Handle__ -> IO ()
52 #if defined(__CONCURRENT_HASKELL__)
57 newHandle v = stToIO (newVar v)
58 readHandle h = stToIO (readVar h)
59 writeHandle h v = stToIO (writeVar h v)
64 %*********************************************************
66 \subsection{Functions}
68 %*********************************************************
71 filePtr :: Handle__ -> ForeignObj
72 filePtr (SemiClosedHandle fp _) = fp
73 filePtr (ReadHandle fp _ _) = fp
74 filePtr (WriteHandle fp _ _) = fp
75 filePtr (AppendHandle fp _ _) = fp
76 filePtr (ReadWriteHandle fp _ _) = fp
78 bufferMode :: Handle__ -> Maybe BufferMode
79 bufferMode (ReadHandle _ m _) = m
80 bufferMode (WriteHandle _ m _) = m
81 bufferMode (AppendHandle _ m _) = m
82 bufferMode (ReadWriteHandle _ m _) = m
84 markHandle :: Handle__ -> Handle__
85 markHandle h@(ReadHandle fp m b)
87 | otherwise = ReadHandle fp m True
88 markHandle h@(WriteHandle fp m b)
90 | otherwise = WriteHandle fp m True
91 markHandle h@(AppendHandle fp m b)
93 | otherwise = AppendHandle fp m True
94 markHandle h@(ReadWriteHandle fp m b)
96 | otherwise = ReadWriteHandle fp m True
99 -------------------------------------------
101 %*********************************************************
103 \subsection[StdHandles]{Standard handles}
105 %*********************************************************
107 Three handles are allocated during program initialisation. The first
108 two manage input or output from the Haskell program's standard input
109 or output channel respectively. The third manages output to the
110 standard error channel. These handles are initially open.
113 stdin, stdout, stderr :: Handle
115 stdin = unsafePerformPrimIO (
116 _ccall_ getLock (``stdin''::Addr) 0 >>= \ rc ->
118 0 -> new_handle ClosedHandle
119 1 -> makeForeignObj (``stdin''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
120 new_handle (ReadHandle fp Nothing False)
121 _ -> constructError "stdin" >>= \ ioError ->
122 new_handle (ErrorHandle ioError)
127 new_handle x = ioToST (newHandle x)
129 stdout = unsafePerformPrimIO (
130 _ccall_ getLock (``stdout''::Addr) 1 >>= \ rc ->
132 0 -> new_handle ClosedHandle
133 1 -> makeForeignObj (``stdout''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
134 new_handle (WriteHandle fp Nothing False)
135 _ -> constructError "stdout" >>= \ ioError ->
136 new_handle (ErrorHandle ioError)
141 new_handle x = ioToST (newHandle x)
143 stderr = unsafePerformPrimIO (
144 _ccall_ getLock (``stderr''::Addr) 1 >>= \ rc ->
146 0 -> new_handle ClosedHandle
147 1 -> makeForeignObj (``stderr''::Addr) (``&freeStdChannel''::Addr) >>= \ fp ->
148 new_handle (WriteHandle fp (Just NoBuffering) False)
149 _ -> constructError "stderr" >>= \ ioError ->
150 new_handle (ErrorHandle ioError)
155 new_handle x = ioToST (newHandle x)
158 %*********************************************************
160 \subsection[OpeningClosing]{Opening and Closing Files}
162 %*********************************************************
165 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
166 deriving (Eq, Ord, Ix, Enum, Read, Show)
168 openFile :: FilePath -> IOMode -> IO Handle
171 stToIO (_ccall_ openFile f m') >>= \ ptr ->
172 if ptr /= ``NULL'' then
173 stToIO (makeForeignObj ptr ((``&freeFile'')::Addr)) >>= \ fp ->
174 newHandle (htype fp Nothing False)
176 stToIO (constructError "openFile") >>= \ ioError@(IOError hn iot msg) ->
178 improved_error -- a HACK, I guess
180 AlreadyExists -> IOError hn AlreadyExists (msg ++ ": " ++ f)
181 NoSuchThing -> IOError hn NoSuchThing (msg ++ ": " ++ f)
182 PermissionDenied -> IOError hn PermissionDenied (msg ++ ": " ++ f)
191 ReadWriteMode -> "r+"
194 ReadMode -> ReadHandle
195 WriteMode -> WriteHandle
196 AppendMode -> AppendHandle
197 ReadWriteMode -> ReadWriteHandle
200 Computation $openFile file mode$ allocates and returns a new, open
201 handle to manage the file {\em file}. It manages input if {\em mode}
202 is $ReadMode$, output if {\em mode} is $WriteMode$ or $AppendMode$,
203 and both input and output if mode is $ReadWriteMode$.
205 If the file does not exist and it is opened for output, it should be
206 created as a new file. If {\em mode} is $WriteMode$ and the file
207 already exists, then it should be truncated to zero length. The
208 handle is positioned at the end of the file if {\em mode} is
209 $AppendMode$, and otherwise at the beginning (in which case its
210 internal position is 0).
212 Implementations should enforce, locally to the Haskell process,
213 multiple-reader single-writer locking on files, which is to say that
214 there may either be many handles on the same file which manage input,
215 or just one handle on the file which manages output. If any open or
216 semi-closed handle is managing a file for output, no new handle can be
217 allocated for that file. If any open or semi-closed handle is
218 managing a file for input, new handles can only be allocated if they
219 do not manage output.
221 Two files are the same if they have the same absolute name. An
222 implementation is free to impose stricter conditions.
225 hClose :: Handle -> IO ()
228 readHandle handle >>= \ htype ->
229 writeHandle handle ClosedHandle >>
231 ErrorHandle ioError ->
234 ioe_closedHandle handle
235 SemiClosedHandle fp (buf,_) ->
236 (if buf /= ``NULL'' then
239 returnPrimIO ()) `thenIO_Prim` \ () ->
240 _casm_ `` %r = (char *)%0; '' fp `thenIO_Prim` \ fp_a ->
241 if fp_a /= (``NULL''::Addr) then -- Under what condition can this be NULL?
242 _ccall_ closeFile fp `thenIO_Prim` \ rc ->
243 {- We explicitly close a file object so that we can be told
244 if there were any errors. Note that after @hClose@
245 has been performed, the ForeignObj embedded in the Handle
246 is still lying around in the heap, so care is taken
247 to avoid closing the file object when the ForeignObj
248 is finalised. (see freeFile()) -}
252 constructErrorAndFail "hClose"
257 _ccall_ closeFile (filePtr other) `thenIO_Prim` \ rc ->
261 constructErrorAndFail "hClose"
264 Computation $hClose hdl$ makes handle {\em hdl} closed. Before the
265 computation finishes, any items buffered for output and not already
266 sent to the operating system are flushed as for $flush$.
268 %*********************************************************
270 \subsection[EOF]{Detecting the End of Input}
272 %*********************************************************
275 For a handle {\em hdl} which attached to a physical file, $hFileSize
276 hdl$ returns the size of {\em hdl} in terms of the number of items
277 which can be read from {\em hdl}.
280 hFileSize :: Handle -> IO Integer
282 readHandle handle >>= \ htype ->
284 ErrorHandle ioError ->
285 writeHandle handle htype >>
288 writeHandle handle htype >>
289 ioe_closedHandle handle
290 SemiClosedHandle _ _ ->
291 writeHandle handle htype >>
292 ioe_closedHandle handle
294 -- HACK! We build a unique MP_INT of the right shape to hold
295 -- a single unsigned word, and we let the C routine change the data bits
296 _casm_ ``%r = 1;'' `thenIO_Prim` \ (I# hack#) ->
297 case int2Integer# hack# of
298 result@(J# _ _ d#) ->
300 bogus_bounds = (error "fileSize"::(Int,Int))
302 _ccall_ fileSize (filePtr other) (ByteArray bogus_bounds d#)
303 `thenIO_Prim` \ rc ->
304 writeHandle handle htype >>
308 constructErrorAndFail "hFileSize"
311 For a readable handle {\em hdl}, computation $hIsEOF hdl$ returns
312 $True$ if no further input can be taken from {\em hdl} or for a
313 physical file, if the current I/O position is equal to the length of
314 the file. Otherwise, it returns $False$.
317 hIsEOF :: Handle -> IO Bool
319 readHandle handle >>= \ htype ->
321 ErrorHandle ioError ->
322 writeHandle handle htype >>
325 writeHandle handle htype >>
326 ioe_closedHandle handle
327 SemiClosedHandle _ _ ->
328 writeHandle handle htype >>
329 ioe_closedHandle handle
331 writeHandle handle htype >>
332 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
333 AppendHandle _ _ _ ->
334 writeHandle handle htype >>
335 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
337 _ccall_ fileEOF (filePtr other) `thenIO_Prim` \ rc ->
338 writeHandle handle (markHandle htype) >>
342 _ -> constructErrorAndFail "hIsEOF"
348 %*********************************************************
350 \subsection[Buffering]{Buffering Operations}
352 %*********************************************************
354 Three kinds of buffering are supported: line-buffering,
355 block-buffering or no-buffering. See @IOBase@ for definition
356 and further explanation of what the type represent.
358 Computation @hSetBuffering hdl mode@ sets the mode of buffering for
359 handle {\em hdl} on subsequent reads and writes.
363 If {\em mode} is @LineBuffering@, line-buffering should be
366 If {\em mode} is @BlockBuffering@ {\em size}, then block-buffering
367 should be enabled if possible. The size of the buffer is {\em n} items
368 if {\em size} is @Just@~{\em n} and is otherwise implementation-dependent.
370 If {\em mode} is @NoBuffering@, then buffering is disabled if possible.
373 If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@
374 to @NoBuffering@, then any items in the output buffer are written to
375 the device, and any items in the input buffer are discarded. The
376 default buffering mode when a handle is opened is
377 implementation-dependent and may depend on the object which is
378 attached to that handle.
381 hSetBuffering :: Handle -> BufferMode -> IO ()
383 hSetBuffering handle mode =
385 (BlockBuffering (Just n))
386 | n <= 0 -> fail (IOError (Just handle) InvalidArgument "illegal buffer size")
388 readHandle handle >>= \ htype ->
389 if isMarked htype then
390 writeHandle handle htype >>
391 fail (IOError (Just handle)
393 "can't set buffering for a dirty handle")
396 ErrorHandle ioError ->
397 writeHandle handle htype >>
400 writeHandle handle htype >>
401 ioe_closedHandle handle
402 SemiClosedHandle _ _ ->
403 writeHandle handle htype >>
404 ioe_closedHandle handle
406 _ccall_ setBuffering (filePtr other) bsize
407 `thenIO_Prim` \ rc ->
409 writeHandle handle ((hcon other) (filePtr other) (Just mode) True)
413 writeHandle handle htype >>
414 constructErrorAndFail "hSetBuffering"
417 isMarked :: Handle__ -> Bool
418 isMarked (ReadHandle fp m b) = b
419 isMarked (WriteHandle fp m b) = b
420 isMarked (AppendHandle fp m b) = b
421 isMarked (ReadWriteHandle fp m b) = b
427 BlockBuffering Nothing -> -2
428 BlockBuffering (Just n) -> n
430 hcon :: Handle__ -> (ForeignObj -> (Maybe BufferMode) -> Bool -> Handle__)
431 hcon (ReadHandle _ _ _) = ReadHandle
432 hcon (WriteHandle _ _ _) = WriteHandle
433 hcon (AppendHandle _ _ _) = AppendHandle
434 hcon (ReadWriteHandle _ _ _) = ReadWriteHandle
437 Computation $flush hdl$ causes any items buffered for output in handle
438 {\em hdl} to be sent immediately to the operating system.
441 hFlush :: Handle -> IO ()
443 readHandle handle >>= \ htype ->
445 ErrorHandle ioError ->
446 writeHandle handle htype >>
449 writeHandle handle htype >>
450 ioe_closedHandle handle
451 SemiClosedHandle _ _ ->
452 writeHandle handle htype >>
453 ioe_closedHandle handle
455 _ccall_ flushFile (filePtr other) `thenIO_Prim` \ rc ->
456 writeHandle handle (markHandle htype) >>
460 constructErrorAndFail "hFlush"
464 %*********************************************************
466 \subsection[Seeking]{Repositioning Handles}
468 %*********************************************************
471 data HandlePosn = HandlePosn Handle Int
473 instance Eq HandlePosn{-partain-}
475 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
476 deriving (Eq, Ord, Ix, Enum, Read, Show)
479 Computation $hGetPosn hdl$ returns the current I/O
480 position of {\em hdl} as an abstract position. Computation
481 $hSetPosn p$ sets the position of {\em hdl}
482 to a previously obtained position {\em p}.
485 hGetPosn :: Handle -> IO HandlePosn
487 readHandle handle >>= \ htype ->
489 ErrorHandle ioError ->
490 writeHandle handle htype >>
493 writeHandle handle htype >>
494 ioe_closedHandle handle
495 SemiClosedHandle _ _ ->
496 writeHandle handle htype >>
497 ioe_closedHandle handle
499 _ccall_ getFilePosn (filePtr other) `thenIO_Prim` \ posn ->
500 writeHandle handle htype >>
502 return (HandlePosn handle posn)
504 constructErrorAndFail "hGetPosn"
506 hSetPosn :: HandlePosn -> IO ()
507 hSetPosn (HandlePosn handle posn) =
508 readHandle handle >>= \ htype ->
510 ErrorHandle ioError ->
511 writeHandle handle htype >>
514 writeHandle handle htype >>
515 ioe_closedHandle handle
516 SemiClosedHandle _ _ ->
517 writeHandle handle htype >>
518 ioe_closedHandle handle
519 AppendHandle _ _ _ ->
520 writeHandle handle htype >>
521 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
523 _ccall_ setFilePosn (filePtr other) posn `thenIO_Prim` \ rc ->
524 writeHandle handle (markHandle htype) >>
528 constructErrorAndFail "hSetPosn"
531 Computation $hSeek hdl mode i$ sets the position of handle
532 {\em hdl} depending on $mode$. If {\em mode} is
534 \item[{\bf AbsoluteSeek}] The position of {\em hdl} is set to {\em i}.
535 \item[{\bf RelativeSeek}] The position of {\em hdl} is set to offset {\em i} from
536 the current position.
537 \item[{\bf SeekToEnd}] The position of {\em hdl} is set to offset {\em i} from
539 \item[{\bf SeekFromBeginning}] The position of {\em hdl} is set to offset {\em i} from
540 the beginning of the file.
543 Some handles may not be seekable $hIsSeekable$, or only support a
544 subset of the possible positioning operations (e.g. it may only be
545 possible to seek to the end of a tape, or to a positive offset from
546 the beginning or current position).
548 It is not possible to set a negative I/O position, or for a physical
549 file, an I/O position beyond the current end-of-file.
552 hSeek :: Handle -> SeekMode -> Integer -> IO ()
553 hSeek handle mode offset@(J# _ s# d#) =
554 readHandle handle >>= \ htype ->
556 ErrorHandle ioError ->
557 writeHandle handle htype >>
560 writeHandle handle htype >>
561 ioe_closedHandle handle
562 SemiClosedHandle _ _ ->
563 writeHandle handle htype >>
564 ioe_closedHandle handle
565 AppendHandle _ _ _ ->
566 writeHandle handle htype >>
567 fail (IOError (Just handle) IllegalOperation "handle is not seekable")
569 _ccall_ seekFile (filePtr other) whence (I# s#) (ByteArray (0,0) d#)
570 `thenIO_Prim` \ rc ->
571 writeHandle handle (markHandle htype) >>
575 constructErrorAndFail "hSeek"
578 whence = case mode of
579 AbsoluteSeek -> ``SEEK_SET''
580 RelativeSeek -> ``SEEK_CUR''
581 SeekFromEnd -> ``SEEK_END''
584 %*********************************************************
586 \subsection[Query]{Handle Properties}
588 %*********************************************************
590 A number of operations return information about the properties of a
591 handle. Each of these operations returns $True$ if the
592 handle has the specified property, and $False$
595 Computation $hIsBlockBuffered hdl$ returns $( False, Nothing )$ if
596 {\em hdl} is not block-buffered. Otherwise it returns
597 $( True, size )$, where {\em size} is $Nothing$ for default buffering, and
598 $( Just n )$ for block-buffering of {\em n} bytes.
601 hIsOpen :: Handle -> IO Bool
603 readHandle handle >>= \ htype ->
605 ErrorHandle ioError ->
606 writeHandle handle htype >>
609 writeHandle handle htype >>
611 SemiClosedHandle _ _ ->
612 writeHandle handle htype >>
615 writeHandle handle htype >>
618 hIsClosed :: Handle -> IO Bool
620 readHandle handle >>= \ htype ->
622 ErrorHandle ioError ->
623 writeHandle handle htype >>
626 writeHandle handle htype >>
629 writeHandle handle htype >>
632 hIsReadable :: Handle -> IO Bool
634 readHandle handle >>= \ htype ->
636 ErrorHandle ioError ->
637 writeHandle handle htype >>
640 writeHandle handle htype >>
641 ioe_closedHandle handle
642 SemiClosedHandle _ _ ->
643 writeHandle handle htype >>
644 ioe_closedHandle handle
646 writeHandle handle htype >>
647 return (isReadable other)
649 isReadable (ReadHandle _ _ _) = True
650 isReadable (ReadWriteHandle _ _ _) = True
653 hIsWritable :: Handle -> IO Bool
655 readHandle handle >>= \ htype ->
657 ErrorHandle ioError ->
658 writeHandle handle htype >>
661 writeHandle handle htype >>
662 ioe_closedHandle handle
663 SemiClosedHandle _ _ ->
664 writeHandle handle htype >>
665 ioe_closedHandle handle
667 writeHandle handle htype >>
668 return (isWritable other)
670 isWritable (AppendHandle _ _ _) = True
671 isWritable (WriteHandle _ _ _) = True
672 isWritable (ReadWriteHandle _ _ _) = True
675 getBufferMode :: Handle__ -> PrimIO Handle__
676 getBufferMode htype =
677 case bufferMode htype of
678 Just x -> returnPrimIO htype
680 _ccall_ getBufferMode (filePtr htype) `thenPrimIO` \ rc ->
684 0 -> Just NoBuffering
685 -1 -> Just LineBuffering
686 -2 -> Just (BlockBuffering Nothing)
688 n -> Just (BlockBuffering (Just n))
690 returnPrimIO (case htype of
691 ReadHandle fp _ b -> ReadHandle fp mode b
692 WriteHandle fp _ b -> WriteHandle fp mode b
693 AppendHandle fp _ b -> AppendHandle fp mode b
694 ReadWriteHandle fp _ b -> ReadWriteHandle fp mode b)
696 hIsBlockBuffered :: Handle -> IO (Bool,Maybe Int)
697 hIsBlockBuffered handle =
698 readHandle handle >>= \ htype ->
700 ErrorHandle ioError ->
701 writeHandle handle htype >>
704 writeHandle handle htype >>
705 ioe_closedHandle handle
706 SemiClosedHandle _ _ ->
707 writeHandle handle htype >>
708 ioe_closedHandle handle
710 getBufferMode other `thenIO_Prim` \ other ->
711 case bufferMode other of
712 Just (BlockBuffering size) ->
713 writeHandle handle other >>
716 writeHandle handle other >>
717 return (False, Nothing)
719 constructErrorAndFail "hIsBlockBuffered"
721 hIsLineBuffered :: Handle -> IO Bool
722 hIsLineBuffered handle =
723 readHandle handle >>= \ htype ->
725 ErrorHandle ioError ->
726 writeHandle handle htype >>
729 writeHandle handle htype >>
730 ioe_closedHandle handle
731 SemiClosedHandle _ _ ->
732 writeHandle handle htype >>
733 ioe_closedHandle handle
735 getBufferMode other `thenIO_Prim` \ other ->
736 case bufferMode other of
737 Just LineBuffering ->
738 writeHandle handle other >>
741 writeHandle handle other >>
744 constructErrorAndFail "hIsLineBuffered"
746 hIsNotBuffered :: Handle -> IO Bool
747 hIsNotBuffered handle =
748 readHandle handle >>= \ htype ->
750 ErrorHandle ioError ->
751 writeHandle handle htype >>
754 writeHandle handle htype >>
755 ioe_closedHandle handle
756 SemiClosedHandle _ _ ->
757 writeHandle handle htype >>
758 ioe_closedHandle handle
760 getBufferMode other `thenIO_Prim` \ other ->
761 case bufferMode other of
763 writeHandle handle other >>
766 writeHandle handle other >>
769 constructErrorAndFail "hIsNotBuffered"
771 hGetBuffering :: Handle -> IO BufferMode
772 hGetBuffering handle =
773 readHandle handle >>= \ htype ->
775 ErrorHandle ioError ->
776 writeHandle handle htype >>
779 writeHandle handle htype >>
780 ioe_closedHandle handle
781 SemiClosedHandle _ _ ->
782 writeHandle handle htype >>
783 ioe_closedHandle handle
785 getBufferMode other `thenIO_Prim` \ other ->
786 case bufferMode other of
788 writeHandle handle other >>
791 constructErrorAndFail "hGetBuffering"
793 hIsSeekable :: Handle -> IO Bool
795 readHandle handle >>= \ htype ->
797 ErrorHandle ioError ->
798 writeHandle handle htype >>
801 writeHandle handle htype >>
802 ioe_closedHandle handle
803 SemiClosedHandle _ _ ->
804 writeHandle handle htype >>
805 ioe_closedHandle handle
806 AppendHandle _ _ _ ->
807 writeHandle handle htype >>
810 _ccall_ seekFileP (filePtr other) `thenIO_Prim` \ rc ->
811 writeHandle handle htype >>
815 _ -> constructErrorAndFail "hIsSeekable"
819 %*********************************************************
821 \subsection{Miscellaneous}
823 %*********************************************************
825 These two functions are meant to get things out of @IOErrors@. They don't!
828 ioeGetFileName :: IOError -> Maybe FilePath
829 ioeGetErrorString :: IOError -> String
830 ioeGetHandle :: IOError -> Maybe Handle
832 ioeGetHandle (IOError h _ _) = h
833 ioeGetErrorString (IOError _ iot str) =
838 ioeGetFileName (IOError _ _ str) =
839 case span (/=':') str of
845 Internal function for creating an @IOError@ representing the
846 access of a closed file.
850 ioe_closedHandle :: Handle -> IO a
851 ioe_closedHandle h = fail (IOError (Just h) IllegalOperation "handle is closed")