1 {-# OPTIONS -fno-implicit-prelude #-}
6 -- -----------------------------------------------------------------------------
7 -- $Id: PrelHandle.hsc,v 1.7 2001/05/31 10:03:35 simonmar Exp $
9 -- (c) The University of Glasgow, 1994-2001
11 -- This module defines the basic operations on I/O "handles".
14 withHandle, withHandle', withHandle_,
15 wantWritableHandle, wantReadableHandle, wantSeekableHandle,
17 newEmptyBuffer, allocateBuffer, readCharFromBuffer, writeCharIntoBuffer,
18 flushWriteBufferOnly, flushWriteBuffer, flushReadBuffer, fillReadBuffer,
21 ioe_closedHandle, ioe_EOF, ioe_notReadable, ioe_notWritable,
23 stdin, stdout, stderr,
24 IOMode(..), IOModeEx(..), openFile, openFileEx, openFd,
25 hClose, hFileSize, hIsEOF, isEOF, hLookAhead, hSetBuffering, hSetBinaryMode,
28 HandlePosn(..), hGetPosn, hSetPosn,
31 hIsOpen, hIsClosed, hIsReadable, hIsWritable, hGetBuffering, hIsSeekable,
32 hSetEcho, hGetEcho, hIsTerminalDevice,
33 ioeGetFileName, ioeGetErrorString, ioeGetHandle,
47 import PrelMarshalUtils
56 import PrelRead ( Read )
59 import PrelMaybe ( Maybe(..) )
62 import PrelNum ( Integer(..), Num(..) )
64 import PrelReal ( toInteger )
68 -- -----------------------------------------------------------------------------
71 -- hWaitForInput blocks (should use a timeout)
73 -- unbuffered hGetLine is a bit dodgy
75 -- hSetBuffering: can't change buffering on a stream,
76 -- when the read buffer is non-empty? (no way to flush the buffer)
78 -- ---------------------------------------------------------------------------
79 -- Creating a new handle
81 newFileHandle :: (MVar Handle__ -> IO ()) -> Handle__ -> IO Handle
82 newFileHandle finalizer hc = do
84 addMVarFinalizer m (finalizer m)
87 -- ---------------------------------------------------------------------------
88 -- Working with Handles
91 In the concurrent world, handles are locked during use. This is done
92 by wrapping an MVar around the handle which acts as a mutex over
93 operations on the handle.
95 To avoid races, we use the following bracketing operations. The idea
96 is to obtain the lock, do some operation and replace the lock again,
97 whether the operation succeeded or failed. We also want to handle the
98 case where the thread receives an exception while processing the IO
99 operation: in these cases we also want to relinquish the lock.
101 There are three versions of @withHandle@: corresponding to the three
102 possible combinations of:
104 - the operation may side-effect the handle
105 - the operation may return a result
107 If the operation generates an error or an exception is raised, the
108 orignal handle is always replaced [ this is the case at the moment,
109 but we might want to revisit this in the future --SDM ].
112 {-# INLINE withHandle #-}
113 withHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
114 withHandle fun h@(FileHandle m) act = withHandle' fun h m act
115 withHandle fun h@(DuplexHandle r w) act = do
116 withHandle' fun h r act
117 withHandle' fun h w act
119 withHandle' fun h m act =
122 checkBufferInvariants h_
123 (h',v) <- catchException (act h_)
124 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
125 checkBufferInvariants h'
129 {-# INLINE withHandle_ #-}
130 withHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
131 withHandle_ fun h@(FileHandle m) act = withHandle_' fun h m act
132 withHandle_ fun h@(DuplexHandle m _) act = withHandle_' fun h m act
134 withHandle_' fun h m act =
137 checkBufferInvariants h_
138 v <- catchException (act h_)
139 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
140 checkBufferInvariants h_
144 withAllHandles__ :: String -> Handle -> (Handle__ -> IO Handle__) -> IO ()
145 withAllHandles__ fun h@(FileHandle m) act = withHandle__' fun h m act
146 withAllHandles__ fun h@(DuplexHandle r w) act = do
147 withHandle__' fun h r act
148 withHandle__' fun h w act
150 withHandle__' fun h m act =
153 checkBufferInvariants h_
154 h' <- catchException (act h_)
155 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
156 checkBufferInvariants h'
160 augmentIOError (IOException (IOError _ iot _ str fp)) fun h h_
161 = IOException (IOError (Just h) iot fun str filepath)
162 where filepath | Just _ <- fp = fp
163 | otherwise = Just (haFilePath h_)
164 augmentIOError other_exception _ _ _
167 -- ---------------------------------------------------------------------------
168 -- Wrapper for write operations.
170 wantWritableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
171 wantWritableHandle fun h@(FileHandle m) act
172 = wantWritableHandle' fun h m act
173 wantWritableHandle fun h@(DuplexHandle _ m) act
174 = wantWritableHandle' fun h m act
175 -- ToDo: in the Duplex case, we don't need to checkWritableHandle
178 :: String -> Handle -> MVar Handle__
179 -> (Handle__ -> IO a) -> IO a
180 wantWritableHandle' fun h m act
181 = withHandle_' fun h m (checkWritableHandle act)
183 checkWritableHandle act handle_
184 = case haType handle_ of
185 ClosedHandle -> ioe_closedHandle
186 SemiClosedHandle -> ioe_closedHandle
187 ReadHandle -> ioe_notWritable
188 ReadWriteHandle -> do
189 let ref = haBuffer handle_
192 if not (bufferIsWritable buf)
193 then do b <- flushReadBuffer (haFD handle_) buf
194 return b{ bufState=WriteBuffer }
196 writeIORef ref new_buf
198 _other -> act handle_
200 -- ---------------------------------------------------------------------------
201 -- Wrapper for read operations.
203 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
204 wantReadableHandle fun h@(FileHandle m) act
205 = wantReadableHandle' fun h m act
206 wantReadableHandle fun h@(DuplexHandle m _) act
207 = wantReadableHandle' fun h m act
208 -- ToDo: in the Duplex case, we don't need to checkReadableHandle
211 :: String -> Handle -> MVar Handle__
212 -> (Handle__ -> IO a) -> IO a
213 wantReadableHandle' fun h m act
214 = withHandle_' fun h m (checkReadableHandle act)
216 checkReadableHandle act handle_ =
217 case haType handle_ of
218 ClosedHandle -> ioe_closedHandle
219 SemiClosedHandle -> ioe_closedHandle
220 AppendHandle -> ioe_notReadable
221 WriteHandle -> ioe_notReadable
222 ReadWriteHandle -> do
223 let ref = haBuffer handle_
225 when (bufferIsWritable buf) $ do
226 new_buf <- flushWriteBuffer (haFD handle_) buf
227 writeIORef ref new_buf{ bufState=ReadBuffer }
229 _other -> act handle_
231 -- ---------------------------------------------------------------------------
232 -- Wrapper for seek operations.
234 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
235 wantSeekableHandle fun h@(DuplexHandle _ _) _act =
236 ioException (IOError (Just h) IllegalOperation fun
237 "handle is not seekable" Nothing)
238 wantSeekableHandle fun h@(FileHandle m) act =
239 withHandle_' fun h m (checkSeekableHandle act)
241 checkSeekableHandle act handle_ =
242 case haType handle_ of
243 ClosedHandle -> ioe_closedHandle
244 SemiClosedHandle -> ioe_closedHandle
245 AppendHandle -> ioe_notSeekable
248 -- -----------------------------------------------------------------------------
251 ioe_closedHandle, ioe_EOF,
252 ioe_notReadable, ioe_notWritable, ioe_notSeekable :: IO a
254 ioe_closedHandle = ioException
255 (IOError Nothing IllegalOperation ""
256 "handle is closed" Nothing)
257 ioe_EOF = ioException
258 (IOError Nothing EOF "" "" Nothing)
259 ioe_notReadable = ioException
260 (IOError Nothing IllegalOperation ""
261 "handle is not open for reading" Nothing)
262 ioe_notWritable = ioException
263 (IOError Nothing IllegalOperation ""
264 "handle is not open for writing" Nothing)
265 ioe_notSeekable = ioException
266 (IOError Nothing IllegalOperation ""
267 "handle is not seekable" Nothing)
269 ioe_bufsiz :: Int -> IO a
270 ioe_bufsiz n = ioException
271 (IOError Nothing InvalidArgument "hSetBuffering"
272 ("illegal buffer size " ++ showsPrec 9 n []) Nothing)
273 -- 9 => should be parens'ified.
275 -- -----------------------------------------------------------------------------
278 -- For a duplex handle, we arrange that the read side points to the write side
279 -- (and hence keeps it alive if the read side is alive). This is done by
280 -- having the haType field of the read side be ReadSideHandle with a pointer
281 -- to the write side. The finalizer is then placed on the write side, and
282 -- the handle only gets finalized once, when both sides are no longer
285 addFinalizer :: Handle -> IO ()
286 addFinalizer (FileHandle m) = addMVarFinalizer m (handleFinalizer m)
287 addFinalizer (DuplexHandle _ w) = addMVarFinalizer w (handleFinalizer w)
289 stdHandleFinalizer :: MVar Handle__ -> IO ()
290 stdHandleFinalizer m = do
292 flushWriteBufferOnly h_
294 handleFinalizer :: MVar Handle__ -> IO ()
295 handleFinalizer m = do
297 flushWriteBufferOnly h_
298 let fd = fromIntegral (haFD h_)
300 -- ToDo: closesocket() for a WINSOCK socket?
301 when (fd /= -1) (c_close fd >> return ())
304 -- ---------------------------------------------------------------------------
305 -- Grimy buffer operations
308 checkBufferInvariants h_ = do
309 let ref = haBuffer h_
310 Buffer{ bufWPtr=w, bufRPtr=r, bufSize=size, bufState=state } <- readIORef ref
315 && ( r /= w || (r == 0 && w == 0) )
316 && ( state /= WriteBuffer || r == 0 )
317 && ( state /= WriteBuffer || w < size ) -- write buffer is never full
319 then error "buffer invariant violation"
322 checkBufferInvariants h_ = return ()
325 newEmptyBuffer :: RawBuffer -> BufferState -> Int -> Buffer
326 newEmptyBuffer b state size
327 = Buffer{ bufBuf=b, bufRPtr=0, bufWPtr=0, bufSize=size, bufState=state }
329 allocateBuffer :: Int -> BufferState -> IO Buffer
330 allocateBuffer sz@(I## size) state = IO $ \s ->
331 case newByteArray## size s of { (## s, b ##) ->
332 (## s, newEmptyBuffer b state sz ##) }
334 writeCharIntoBuffer :: RawBuffer -> Int -> Char -> IO Int
335 writeCharIntoBuffer slab (I## off) (C## c)
336 = IO $ \s -> case writeCharArray## slab off c s of
337 s -> (## s, I## (off +## 1##) ##)
339 readCharFromBuffer :: RawBuffer -> Int -> IO (Char, Int)
340 readCharFromBuffer slab (I## off)
341 = IO $ \s -> case readCharArray## slab off s of
342 (## s, c ##) -> (## s, (C## c, I## (off +## 1##)) ##)
344 dEFAULT_BUFFER_SIZE = (#const BUFSIZ) :: Int
346 getBuffer :: FD -> BufferState -> IO (IORef Buffer, BufferMode)
347 getBuffer fd state = do
348 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE state
349 ioref <- newIORef buffer
353 | is_tty = LineBuffering
354 | otherwise = BlockBuffering Nothing
356 return (ioref, buffer_mode)
358 mkUnBuffer :: IO (IORef Buffer)
360 buffer <- allocateBuffer 1 ReadBuffer
363 -- flushWriteBufferOnly flushes the buffer iff it contains pending write data.
364 flushWriteBufferOnly :: Handle__ -> IO ()
365 flushWriteBufferOnly h_ = do
369 new_buf <- if bufferIsWritable buf
370 then flushWriteBuffer fd buf
372 writeIORef ref new_buf
374 -- flushBuffer syncs the file with the buffer, including moving the
375 -- file pointer backwards in the case of a read buffer.
376 flushBuffer :: Handle__ -> IO ()
378 let ref = haBuffer h_
383 ReadBuffer -> flushReadBuffer (haFD h_) buf
384 WriteBuffer -> flushWriteBuffer (haFD h_) buf
386 writeIORef ref flushed_buf
388 -- When flushing a read buffer, we seek backwards by the number of
389 -- characters in the buffer. The file descriptor must therefore be
390 -- seekable: attempting to flush the read buffer on an unseekable
391 -- handle is not allowed.
392 flushReadBuffer :: FD -> Buffer -> IO Buffer
393 flushReadBuffer fd buf
394 | bufferEmpty buf = return buf
396 let off = negate (bufWPtr buf - bufRPtr buf)
397 throwErrnoIfMinus1Retry "flushReadBuffer"
398 (c_lseek (fromIntegral fd) (fromIntegral off) (#const SEEK_CUR))
399 return buf{ bufWPtr=0, bufRPtr=0 }
401 flushWriteBuffer :: FD -> Buffer -> IO Buffer
402 flushWriteBuffer fd buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = do
405 puts ("flushWriteBuffer, fd=" ++ show fd ++ ", bytes=" ++ show bytes ++ "\n")
408 then return (buf{ bufRPtr=0, bufWPtr=0 })
410 res <- throwErrnoIfMinus1RetryMayBlock "flushWriteBuffer"
411 (write_off (fromIntegral fd) b (fromIntegral r)
412 (fromIntegral bytes))
414 let res' = fromIntegral res
416 then flushWriteBuffer fd (buf{ bufRPtr = r + res' })
417 else return buf{ bufRPtr=0, bufWPtr=0 }
419 foreign import "write_wrap" unsafe
420 write_off :: CInt -> RawBuffer -> Int -> CInt -> IO CInt
422 int write_wrap(int fd, void *ptr, HsInt off, int size) \
423 { return write(fd, ptr + off, size); }
426 fillReadBuffer :: FD -> Bool -> Buffer -> IO Buffer
427 fillReadBuffer fd is_line
428 buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w, bufSize=size } =
429 -- buffer better be empty:
430 assert (r == 0 && w == 0) $ do
431 fillReadBufferLoop fd is_line buf b w size
433 -- For a line buffer, we just get the first chunk of data to arrive,
434 -- and don't wait for the whole buffer to be full (but we *do* wait
435 -- until some data arrives). This isn't really line buffering, but it
436 -- appears to be what GHC has done for a long time, and I suspect it
437 -- is more useful than line buffering in most cases.
439 fillReadBufferLoop fd is_line buf b w size = do
441 if bytes == 0 -- buffer full?
442 then return buf{ bufRPtr=0, bufWPtr=w }
445 puts ("fillReadBufferLoop: bytes = " ++ show bytes ++ "\n")
447 res <- throwErrnoIfMinus1RetryMayBlock "fillReadBuffer"
448 (read_off fd b (fromIntegral w) (fromIntegral bytes))
450 let res' = fromIntegral res
454 else return buf{ bufRPtr=0, bufWPtr=w }
455 else if res' < bytes && not is_line
456 then fillReadBufferLoop fd is_line buf b (w+res') size
457 else return buf{ bufRPtr=0, bufWPtr=w+res' }
459 foreign import "read_wrap" unsafe
460 read_off :: FD -> RawBuffer -> Int -> CInt -> IO CInt
462 int read_wrap(int fd, void *ptr, HsInt off, int size) \
463 { return read(fd, ptr + off, size); }
465 -- ---------------------------------------------------------------------------
468 -- Three handles are allocated during program initialisation. The first
469 -- two manage input or output from the Haskell program's standard input
470 -- or output channel respectively. The third manages output to the
471 -- standard error channel. These handles are initially open.
478 stdin = unsafePerformIO $ do
479 -- ToDo: acquire lock
480 setNonBlockingFD fd_stdin
481 (buf, bmode) <- getBuffer fd_stdin ReadBuffer
482 spares <- newIORef BufferListNil
483 newFileHandle stdHandleFinalizer
484 (Handle__ { haFD = fd_stdin,
486 haBufferMode = bmode,
487 haFilePath = "<stdin>",
493 stdout = unsafePerformIO $ do
494 -- ToDo: acquire lock
495 -- We don't set non-blocking mode on stdout or sterr, because
496 -- some shells don't recover properly.
497 -- setNonBlockingFD fd_stdout
498 (buf, bmode) <- getBuffer fd_stdout WriteBuffer
499 spares <- newIORef BufferListNil
500 newFileHandle stdHandleFinalizer
501 (Handle__ { haFD = fd_stdout,
502 haType = WriteHandle,
503 haBufferMode = bmode,
504 haFilePath = "<stdout>",
510 stderr = unsafePerformIO $ do
511 -- ToDo: acquire lock
512 -- We don't set non-blocking mode on stdout or sterr, because
513 -- some shells don't recover properly.
514 -- setNonBlockingFD fd_stderr
516 spares <- newIORef BufferListNil
517 newFileHandle stdHandleFinalizer
518 (Handle__ { haFD = fd_stderr,
519 haType = WriteHandle,
520 haBufferMode = NoBuffering,
521 haFilePath = "<stderr>",
526 -- ---------------------------------------------------------------------------
527 -- Opening and Closing Files
530 Computation `openFile file mode' allocates and returns a new, open
531 handle to manage the file `file'. It manages input if `mode'
532 is `ReadMode', output if `mode' is `WriteMode' or `AppendMode',
533 and both input and output if mode is `ReadWriteMode'.
535 If the file does not exist and it is opened for output, it should be
536 created as a new file. If `mode' is `WriteMode' and the file
537 already exists, then it should be truncated to zero length. The
538 handle is positioned at the end of the file if `mode' is
539 `AppendMode', and otherwise at the beginning (in which case its
540 internal position is 0).
542 Implementations should enforce, locally to the Haskell process,
543 multiple-reader single-writer locking on files, which is to say that
544 there may either be many handles on the same file which manage input,
545 or just one handle on the file which manages output. If any open or
546 semi-closed handle is managing a file for output, no new handle can be
547 allocated for that file. If any open or semi-closed handle is
548 managing a file for input, new handles can only be allocated if they
549 do not manage output.
551 Two files are the same if they have the same absolute name. An
552 implementation is free to impose stricter conditions.
555 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
556 deriving (Eq, Ord, Ix, Enum, Read, Show)
561 deriving (Eq, Read, Show)
563 addFilePathToIOError fun fp (IOException (IOError h iot _ str _))
564 = IOException (IOError h iot fun str (Just fp))
565 addFilePathToIOError _ _ other_exception
568 openFile :: FilePath -> IOMode -> IO Handle
571 (openFile' fp (TextMode im))
572 (\e -> throw (addFilePathToIOError "openFile" fp e))
574 openFileEx :: FilePath -> IOModeEx -> IO Handle
578 (\e -> throw (addFilePathToIOError "openFileEx" fp e))
581 openFile' filepath ex_mode =
582 withCString filepath $ \ f ->
587 BinaryMode bmo -> (bmo, True)
588 TextMode tmo -> (tmo, False)
590 oflags1 = case mode of
591 ReadMode -> read_flags
592 WriteMode -> write_flags
593 ReadWriteMode -> rw_flags
594 AppendMode -> append_flags
602 oflags = oflags1 .|. binary_flags
605 -- the old implementation had a complicated series of three opens,
606 -- which is perhaps because we have to be careful not to open
607 -- directories. However, the man pages I've read say that open()
608 -- always returns EISDIR if the file is a directory and was opened
609 -- for writing, so I think we're ok with a single open() here...
610 fd <- fromIntegral `liftM`
611 throwErrnoIfMinus1Retry "openFile"
612 (c_open f (fromIntegral oflags) 0o666)
614 openFd fd filepath mode
617 std_flags = o_NONBLOCK .|. o_NOCTTY
618 output_flags = std_flags .|. o_CREAT
619 read_flags = std_flags .|. o_RDONLY
620 write_flags = output_flags .|. o_WRONLY .|. o_TRUNC
621 rw_flags = output_flags .|. o_RDWR
622 append_flags = output_flags .|. o_WRONLY .|. o_APPEND
624 -- ---------------------------------------------------------------------------
627 openFd :: FD -> FilePath -> IOMode -> IO Handle
628 openFd fd filepath mode = do
629 -- turn on non-blocking mode
632 let (ha_type, write) =
634 ReadMode -> ( ReadHandle, False )
635 WriteMode -> ( WriteHandle, True )
636 ReadWriteMode -> ( ReadWriteHandle, True )
637 AppendMode -> ( AppendHandle, True )
639 -- open() won't tell us if it was a directory if we only opened for
640 -- reading, so check again.
644 ioException (IOError Nothing InappropriateType "openFile"
645 "is a directory" Nothing)
648 | ReadWriteHandle <- ha_type -> mkDuplexHandle fd filepath
649 | otherwise -> mkFileHandle fd filepath ha_type
651 -- regular files need to be locked
653 r <- lockFile (fromIntegral fd) (fromBool write) 1{-exclusive-}
655 ioException (IOError Nothing ResourceBusy "openFile"
656 "file is locked" Nothing)
657 mkFileHandle fd filepath ha_type
660 foreign import "lockFile" unsafe
661 lockFile :: CInt -> CInt -> CInt -> IO CInt
663 foreign import "unlockFile" unsafe
664 unlockFile :: CInt -> IO CInt
666 mkFileHandle :: FD -> FilePath -> HandleType -> IO Handle
667 mkFileHandle fd filepath ha_type = do
668 (buf, bmode) <- getBuffer fd (initBufferState ha_type)
669 spares <- newIORef BufferListNil
670 newFileHandle handleFinalizer
671 (Handle__ { haFD = fd,
673 haBufferMode = bmode,
674 haFilePath = filepath,
679 mkDuplexHandle :: FD -> FilePath -> IO Handle
680 mkDuplexHandle fd filepath = do
681 (w_buf, w_bmode) <- getBuffer fd WriteBuffer
682 w_spares <- newIORef BufferListNil
684 Handle__ { haFD = fd,
685 haType = WriteHandle,
686 haBufferMode = w_bmode,
687 haFilePath = filepath,
691 write_side <- newMVar w_handle_
693 (r_buf, r_bmode) <- getBuffer fd ReadBuffer
694 r_spares <- newIORef BufferListNil
696 Handle__ { haFD = fd,
697 haType = ReadSideHandle write_side,
698 haBufferMode = r_bmode,
699 haFilePath = filepath,
703 read_side <- newMVar r_handle_
705 addMVarFinalizer write_side (handleFinalizer write_side)
706 return (DuplexHandle read_side write_side)
709 initBufferState ReadHandle = ReadBuffer
710 initBufferState _ = WriteBuffer
712 -- ---------------------------------------------------------------------------
715 -- Computation `hClose hdl' makes handle `hdl' closed. Before the
716 -- computation finishes, any items buffered for output and not already
717 -- sent to the operating system are flushed as for `hFlush'.
719 -- For a duplex handle, we close&flush the write side, and just close
722 hClose :: Handle -> IO ()
723 hClose h@(FileHandle m) = hClose' h m
724 hClose h@(DuplexHandle r w) = do
726 withHandle__' "hClose" h r $ \ handle_ -> do
727 return handle_{ haFD = -1,
728 haType = ClosedHandle
732 withHandle__' "hClose" h m $ \ handle_ -> do
733 case haType handle_ of
734 ClosedHandle -> return handle_
736 let fd = fromIntegral (haFD handle_)
737 flushWriteBufferOnly handle_
738 throwErrnoIfMinus1Retry_ "hClose" (c_close fd)
740 -- free the spare buffers
741 writeIORef (haBuffers handle_) BufferListNil
746 -- we must set the fd to -1, because the finalizer is going
747 -- to run eventually and try to close/unlock it.
748 return (handle_{ haFD = -1,
749 haType = ClosedHandle
752 -----------------------------------------------------------------------------
753 -- Detecting the size of a file
755 -- For a handle `hdl' which attached to a physical file, `hFileSize
756 -- hdl' returns the size of `hdl' in terms of the number of items
757 -- which can be read from `hdl'.
759 hFileSize :: Handle -> IO Integer
761 withHandle_ "hFileSize" handle $ \ handle_ -> do
762 case haType handle_ of
763 ClosedHandle -> ioe_closedHandle
764 SemiClosedHandle -> ioe_closedHandle
765 _ -> do flushWriteBufferOnly handle_
766 r <- fdFileSize (haFD handle_)
769 else ioException (IOError Nothing InappropriateType "hFileSize"
770 "not a regular file" Nothing)
772 -- ---------------------------------------------------------------------------
773 -- Detecting the End of Input
775 -- For a readable handle `hdl', `hIsEOF hdl' returns
776 -- `True' if no further input can be taken from `hdl' or for a
777 -- physical file, if the current I/O position is equal to the length of
778 -- the file. Otherwise, it returns `False'.
780 hIsEOF :: Handle -> IO Bool
783 (do hLookAhead handle; return False)
784 (\e -> if isEOFError e then return True else throw e)
789 -- ---------------------------------------------------------------------------
792 -- hLookahead returns the next character from the handle without
793 -- removing it from the input buffer, blocking until a character is
796 hLookAhead :: Handle -> IO Char
797 hLookAhead handle = do
798 wantReadableHandle "hLookAhead" handle $ \handle_ -> do
799 let ref = haBuffer handle_
801 is_line = haBufferMode handle_ == LineBuffering
804 -- fill up the read buffer if necessary
805 new_buf <- if bufferEmpty buf
806 then fillReadBuffer fd is_line buf
809 writeIORef ref new_buf
811 (c,_) <- readCharFromBuffer (bufBuf buf) (bufRPtr buf)
814 -- ---------------------------------------------------------------------------
815 -- Buffering Operations
817 -- Three kinds of buffering are supported: line-buffering,
818 -- block-buffering or no-buffering. See PrelIOBase for definition and
819 -- further explanation of what the type represent.
821 -- Computation `hSetBuffering hdl mode' sets the mode of buffering for
822 -- handle hdl on subsequent reads and writes.
824 -- * If mode is LineBuffering, line-buffering should be enabled if possible.
826 -- * If mode is `BlockBuffering size', then block-buffering
827 -- should be enabled if possible. The size of the buffer is n items
828 -- if size is `Just n' and is otherwise implementation-dependent.
830 -- * If mode is NoBuffering, then buffering is disabled if possible.
832 -- If the buffer mode is changed from BlockBuffering or
833 -- LineBuffering to NoBuffering, then any items in the output
834 -- buffer are written to the device, and any items in the input buffer
835 -- are discarded. The default buffering mode when a handle is opened
836 -- is implementation-dependent and may depend on the object which is
837 -- attached to that handle.
839 hSetBuffering :: Handle -> BufferMode -> IO ()
840 hSetBuffering handle mode =
841 withAllHandles__ "hSetBuffering" handle $ \ handle_ -> do
842 case haType handle_ of
843 ClosedHandle -> ioe_closedHandle
846 - we flush the old buffer regardless of whether
847 the new buffer could fit the contents of the old buffer
849 - allow a handle's buffering to change even if IO has
850 occurred (ANSI C spec. does not allow this, nor did
851 the previous implementation of IO.hSetBuffering).
852 - a non-standard extension is to allow the buffering
853 of semi-closed handles to change [sof 6/98]
857 let state = initBufferState (haType handle_)
860 -- we always have a 1-character read buffer for
861 -- unbuffered handles: it's needed to
862 -- support hLookAhead.
863 NoBuffering -> allocateBuffer 1 ReadBuffer
864 LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state
865 BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state
866 BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n
867 | otherwise -> allocateBuffer n state
868 writeIORef (haBuffer handle_) new_buf
870 -- for input terminals we need to put the terminal into
871 -- cooked or raw mode depending on the type of buffering.
872 is_tty <- fdIsTTY (haFD handle_)
873 when (is_tty && isReadableHandleType (haType handle_)) $
875 NoBuffering -> setCooked (haFD handle_) False
876 _ -> setCooked (haFD handle_) True
878 -- throw away spare buffers, they might be the wrong size
879 writeIORef (haBuffers handle_) BufferListNil
881 return (handle_{ haBufferMode = mode })
883 -- -----------------------------------------------------------------------------
886 -- The action `hFlush hdl' causes any items buffered for output
887 -- in handle `hdl' to be sent immediately to the operating
890 hFlush :: Handle -> IO ()
892 wantWritableHandle "hFlush" handle $ \ handle_ -> do
893 buf <- readIORef (haBuffer handle_)
894 if bufferIsWritable buf && not (bufferEmpty buf)
895 then do flushed_buf <- flushWriteBuffer (haFD handle_) buf
896 writeIORef (haBuffer handle_) flushed_buf
900 -- -----------------------------------------------------------------------------
901 -- Repositioning Handles
903 data HandlePosn = HandlePosn Handle HandlePosition
905 instance Eq HandlePosn where
906 (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2
908 -- HandlePosition is the Haskell equivalent of POSIX' off_t.
909 -- We represent it as an Integer on the Haskell side, but
910 -- cheat slightly in that hGetPosn calls upon a C helper
911 -- that reports the position back via (merely) an Int.
912 type HandlePosition = Integer
914 -- Computation `hGetPosn hdl' returns the current I/O position of
915 -- `hdl' as an abstract position. Computation `hSetPosn p' sets the
916 -- position of `hdl' to a previously obtained position `p'.
918 hGetPosn :: Handle -> IO HandlePosn
920 wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
923 -- urgh, on Windows we have to worry about \n -> \r\n translation,
924 -- so we can't easily calculate the file position using the
925 -- current buffer size. Just flush instead.
929 let fd = fromIntegral (haFD handle_)
930 posn <- fromIntegral `liftM`
931 throwErrnoIfMinus1Retry "hGetPosn"
932 (c_lseek fd 0 (#const SEEK_CUR))
934 let ref = haBuffer handle_
938 | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf)
939 | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf)
941 return (HandlePosn handle real_posn)
944 hSetPosn :: HandlePosn -> IO ()
945 hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i
947 -- ---------------------------------------------------------------------------
951 The action `hSeek hdl mode i' sets the position of handle
952 `hdl' depending on `mode'. If `mode' is
954 * AbsoluteSeek - The position of `hdl' is set to `i'.
955 * RelativeSeek - The position of `hdl' is set to offset `i' from
956 the current position.
957 * SeekFromEnd - The position of `hdl' is set to offset `i' from
960 Some handles may not be seekable (see `hIsSeekable'), or only
961 support a subset of the possible positioning operations (e.g. it may
962 only be possible to seek to the end of a tape, or to a positive
963 offset from the beginning or current position).
965 It is not possible to set a negative I/O position, or for a physical
966 file, an I/O position beyond the current end-of-file.
969 - when seeking using `SeekFromEnd', positive offsets (>=0) means
970 seeking at or past EOF.
972 - we possibly deviate from the report on the issue of seeking within
973 the buffer and whether to flush it or not. The report isn't exactly
977 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
978 deriving (Eq, Ord, Ix, Enum, Read, Show)
980 hSeek :: Handle -> SeekMode -> Integer -> IO ()
981 hSeek handle mode offset =
982 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
983 let ref = haBuffer handle_
990 throwErrnoIfMinus1Retry_ "hSeek"
991 (c_lseek (fromIntegral (haFD handle_)) (fromIntegral offset) whence)
994 whence = case mode of
995 AbsoluteSeek -> (#const SEEK_SET)
996 RelativeSeek -> (#const SEEK_CUR)
997 SeekFromEnd -> (#const SEEK_END)
999 if bufferIsWritable buf
1000 then do new_buf <- flushWriteBuffer fd buf
1001 writeIORef ref new_buf
1005 if mode == RelativeSeek && offset >= 0 && offset < fromIntegral (w - r)
1006 then writeIORef ref buf{ bufRPtr = r + fromIntegral offset }
1009 new_buf <- flushReadBuffer (haFD handle_) buf
1010 writeIORef ref new_buf
1013 -- -----------------------------------------------------------------------------
1014 -- Handle Properties
1016 -- A number of operations return information about the properties of a
1017 -- handle. Each of these operations returns `True' if the handle has
1018 -- the specified property, and `False' otherwise.
1020 hIsOpen :: Handle -> IO Bool
1022 withHandle_ "hIsOpen" handle $ \ handle_ -> do
1023 case haType handle_ of
1024 ClosedHandle -> return False
1025 SemiClosedHandle -> return False
1028 hIsClosed :: Handle -> IO Bool
1030 withHandle_ "hIsClosed" handle $ \ handle_ -> do
1031 case haType handle_ of
1032 ClosedHandle -> return True
1035 {- not defined, nor exported, but mentioned
1036 here for documentation purposes:
1038 hSemiClosed :: Handle -> IO Bool
1042 return (not (ho || hc))
1045 hIsReadable :: Handle -> IO Bool
1046 hIsReadable (DuplexHandle _ _) = return True
1047 hIsReadable handle =
1048 withHandle_ "hIsReadable" handle $ \ handle_ -> do
1049 case haType handle_ of
1050 ClosedHandle -> ioe_closedHandle
1051 SemiClosedHandle -> ioe_closedHandle
1052 htype -> return (isReadableHandleType htype)
1054 hIsWritable :: Handle -> IO Bool
1055 hIsWritable (DuplexHandle _ _) = return False
1056 hIsWritable handle =
1057 withHandle_ "hIsWritable" handle $ \ handle_ -> do
1058 case haType handle_ of
1059 ClosedHandle -> ioe_closedHandle
1060 SemiClosedHandle -> ioe_closedHandle
1061 htype -> return (isWritableHandleType htype)
1063 -- Querying how a handle buffers its data:
1065 hGetBuffering :: Handle -> IO BufferMode
1066 hGetBuffering handle =
1067 withHandle_ "hGetBuffering" handle $ \ handle_ -> do
1068 case haType handle_ of
1069 ClosedHandle -> ioe_closedHandle
1071 -- We're being non-standard here, and allow the buffering
1072 -- of a semi-closed handle to be queried. -- sof 6/98
1073 return (haBufferMode handle_) -- could be stricter..
1075 hIsSeekable :: Handle -> IO Bool
1076 hIsSeekable handle =
1077 withHandle_ "hIsSeekable" handle $ \ handle_ -> do
1078 case haType handle_ of
1079 ClosedHandle -> ioe_closedHandle
1080 SemiClosedHandle -> ioe_closedHandle
1081 AppendHandle -> return False
1082 _ -> do t <- fdType (haFD handle_)
1083 return (t == RegularFile)
1085 -- -----------------------------------------------------------------------------
1086 -- Changing echo status
1088 -- Non-standard GHC extension is to allow the echoing status
1089 -- of a handles connected to terminals to be reconfigured:
1091 hSetEcho :: Handle -> Bool -> IO ()
1092 hSetEcho handle on = do
1093 isT <- hIsTerminalDevice handle
1097 withHandle_ "hSetEcho" handle $ \ handle_ -> do
1098 case haType handle_ of
1099 ClosedHandle -> ioe_closedHandle
1100 _ -> setEcho (haFD handle_) on
1102 hGetEcho :: Handle -> IO Bool
1103 hGetEcho handle = do
1104 isT <- hIsTerminalDevice handle
1108 withHandle_ "hGetEcho" handle $ \ handle_ -> do
1109 case haType handle_ of
1110 ClosedHandle -> ioe_closedHandle
1111 _ -> getEcho (haFD handle_)
1113 hIsTerminalDevice :: Handle -> IO Bool
1114 hIsTerminalDevice handle = do
1115 withHandle_ "hIsTerminalDevice" handle $ \ handle_ -> do
1116 case haType handle_ of
1117 ClosedHandle -> ioe_closedHandle
1118 _ -> fdIsTTY (haFD handle_)
1120 -- -----------------------------------------------------------------------------
1124 hSetBinaryMode handle bin =
1125 withHandle_ "hSetBinaryMode" handle $ \ handle_ ->
1126 do let flg | bin = (#const O_BINARY)
1127 | otherwise = (#const O_TEXT)
1128 throwErrnoIfMinus1_ "hSetBinaryMode"
1129 (setmode (fromIntegral (haFD handle_)) flg)
1131 foreign import "setmode" setmode :: CInt -> CInt -> IO CInt
1133 hSetBinaryMode _ _ = return ()
1136 -- -----------------------------------------------------------------------------
1139 -- These three functions are meant to get things out of an IOError.
1141 ioeGetFileName :: IOError -> Maybe FilePath
1142 ioeGetErrorString :: IOError -> String
1143 ioeGetHandle :: IOError -> Maybe Handle
1145 ioeGetHandle (IOException (IOError h _ _ _ _)) = h
1146 ioeGetHandle (UserError _) = Nothing
1147 ioeGetHandle _ = error "IO.ioeGetHandle: not an IO error"
1149 ioeGetErrorString (IOException (IOError _ iot _ _ _)) = show iot
1150 ioeGetErrorString (UserError str) = str
1151 ioeGetErrorString _ = error "IO.ioeGetErrorString: not an IO error"
1153 ioeGetFileName (IOException (IOError _ _ _ _ fn)) = fn
1154 ioeGetFileName (UserError _) = Nothing
1155 ioeGetFileName _ = error "IO.ioeGetFileName: not an IO error"
1157 -- ---------------------------------------------------------------------------
1161 puts :: String -> IO ()
1162 puts s = withCString s $ \cstr -> do c_write 1 cstr (fromIntegral (length s))