1 {-# OPTIONS -fno-implicit-prelude -#include "HsBase.h" #-}
6 -----------------------------------------------------------------------------
9 -- Copyright : (c) The University of Glasgow, 1994-2001
10 -- License : see libraries/base/LICENSE
12 -- Maintainer : libraries@haskell.org
13 -- Stability : internal
14 -- Portability : non-portable
16 -- This module defines the basic operations on I\/O \"handles\".
18 -----------------------------------------------------------------------------
21 withHandle, withHandle', withHandle_,
22 wantWritableHandle, wantReadableHandle, wantSeekableHandle,
24 newEmptyBuffer, allocateBuffer, readCharFromBuffer, writeCharIntoBuffer,
25 flushWriteBufferOnly, flushWriteBuffer, flushReadBuffer, fillReadBuffer,
26 read_off, read_off_ba,
27 write_off, write_off_ba, unlockFile,
29 ioe_closedHandle, ioe_EOF, ioe_notReadable, ioe_notWritable,
31 stdin, stdout, stderr,
32 IOMode(..), IOModeEx(..), openFile, openFileEx, openFd, fdToHandle,
33 hFileSize, hIsEOF, isEOF, hLookAhead, hSetBuffering, hSetBinaryMode,
34 hFlush, hDuplicate, hDuplicateTo,
38 HandlePosn(..), hGetPosn, hSetPosn,
39 SeekMode(..), hSeek, hTell,
41 hIsOpen, hIsClosed, hIsReadable, hIsWritable, hGetBuffering, hIsSeekable,
42 hSetEcho, hGetEcho, hIsTerminalDevice,
55 import System.IO.Error
62 import GHC.Read ( Read )
67 import GHC.Num ( Integer(..), Num(..) )
69 import GHC.Real ( toInteger )
73 -- -----------------------------------------------------------------------------
76 -- hWaitForInput blocks (should use a timeout)
78 -- unbuffered hGetLine is a bit dodgy
80 -- hSetBuffering: can't change buffering on a stream,
81 -- when the read buffer is non-empty? (no way to flush the buffer)
83 -- ---------------------------------------------------------------------------
84 -- Are files opened by default in text or binary mode, if the user doesn't
87 dEFAULT_OPEN_IN_BINARY_MODE = False :: Bool
89 -- ---------------------------------------------------------------------------
90 -- Creating a new handle
92 newFileHandle :: (MVar Handle__ -> IO ()) -> Handle__ -> IO Handle
93 newFileHandle finalizer hc = do
95 addMVarFinalizer m (finalizer m)
98 -- ---------------------------------------------------------------------------
99 -- Working with Handles
102 In the concurrent world, handles are locked during use. This is done
103 by wrapping an MVar around the handle which acts as a mutex over
104 operations on the handle.
106 To avoid races, we use the following bracketing operations. The idea
107 is to obtain the lock, do some operation and replace the lock again,
108 whether the operation succeeded or failed. We also want to handle the
109 case where the thread receives an exception while processing the IO
110 operation: in these cases we also want to relinquish the lock.
112 There are three versions of @withHandle@: corresponding to the three
113 possible combinations of:
115 - the operation may side-effect the handle
116 - the operation may return a result
118 If the operation generates an error or an exception is raised, the
119 original handle is always replaced [ this is the case at the moment,
120 but we might want to revisit this in the future --SDM ].
123 {-# INLINE withHandle #-}
124 withHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
125 withHandle fun h@(FileHandle m) act = withHandle' fun h m act
126 withHandle fun h@(DuplexHandle m _) act = withHandle' fun h m act
128 withHandle' :: String -> Handle -> MVar Handle__
129 -> (Handle__ -> IO (Handle__,a)) -> IO a
130 withHandle' fun h m act =
133 checkBufferInvariants h_
134 (h',v) <- catch (act h_)
135 (\ ex -> putMVar m h_ >> ioError (augmentIOError ex fun h h_))
136 checkBufferInvariants h'
140 {-# INLINE withHandle_ #-}
141 withHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
142 withHandle_ fun h@(FileHandle m) act = withHandle_' fun h m act
143 withHandle_ fun h@(DuplexHandle m _) act = withHandle_' fun h m act
145 withHandle_' fun h m act =
148 checkBufferInvariants h_
150 (\ ex -> putMVar m h_ >> ioError (augmentIOError ex fun h h_))
151 checkBufferInvariants h_
155 withAllHandles__ :: String -> Handle -> (Handle__ -> IO Handle__) -> IO ()
156 withAllHandles__ fun h@(FileHandle m) act = withHandle__' fun h m act
157 withAllHandles__ fun h@(DuplexHandle r w) act = do
158 withHandle__' fun h r act
159 withHandle__' fun h w act
161 withHandle__' fun h m act =
164 checkBufferInvariants h_
166 (\ ex -> putMVar m h_ >> ioError (augmentIOError ex fun h h_))
167 checkBufferInvariants h'
171 augmentIOError (IOError _ iot _ str fp) fun h h_
172 = IOError (Just h) iot fun str filepath
173 where filepath | Just _ <- fp = fp
174 | otherwise = Just (haFilePath h_)
176 -- ---------------------------------------------------------------------------
177 -- Wrapper for write operations.
179 wantWritableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
180 wantWritableHandle fun h@(FileHandle m) act
181 = wantWritableHandle' fun h m act
182 wantWritableHandle fun h@(DuplexHandle _ m) act
183 = wantWritableHandle' fun h m act
184 -- ToDo: in the Duplex case, we don't need to checkWritableHandle
187 :: String -> Handle -> MVar Handle__
188 -> (Handle__ -> IO a) -> IO a
189 wantWritableHandle' fun h m act
190 = withHandle_' fun h m (checkWritableHandle act)
192 checkWritableHandle act handle_
193 = case haType handle_ of
194 ClosedHandle -> ioe_closedHandle
195 SemiClosedHandle -> ioe_closedHandle
196 ReadHandle -> ioe_notWritable
197 ReadWriteHandle -> do
198 let ref = haBuffer handle_
201 if not (bufferIsWritable buf)
202 then do b <- flushReadBuffer (haFD handle_) buf
203 return b{ bufState=WriteBuffer }
205 writeIORef ref new_buf
207 _other -> act handle_
209 -- ---------------------------------------------------------------------------
210 -- Wrapper for read operations.
212 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
213 wantReadableHandle fun h@(FileHandle m) act
214 = wantReadableHandle' fun h m act
215 wantReadableHandle fun h@(DuplexHandle m _) act
216 = wantReadableHandle' fun h m act
217 -- ToDo: in the Duplex case, we don't need to checkReadableHandle
220 :: String -> Handle -> MVar Handle__
221 -> (Handle__ -> IO a) -> IO a
222 wantReadableHandle' fun h m act
223 = withHandle_' fun h m (checkReadableHandle act)
225 checkReadableHandle act handle_ =
226 case haType handle_ of
227 ClosedHandle -> ioe_closedHandle
228 SemiClosedHandle -> ioe_closedHandle
229 AppendHandle -> ioe_notReadable
230 WriteHandle -> ioe_notReadable
231 ReadWriteHandle -> do
232 let ref = haBuffer handle_
234 when (bufferIsWritable buf) $ do
235 new_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf
236 writeIORef ref new_buf{ bufState=ReadBuffer }
238 _other -> act handle_
240 -- ---------------------------------------------------------------------------
241 -- Wrapper for seek operations.
243 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
244 wantSeekableHandle fun h@(DuplexHandle _ _) _act =
245 ioException (IOError (Just h) IllegalOperation fun
246 "handle is not seekable" Nothing)
247 wantSeekableHandle fun h@(FileHandle m) act =
248 withHandle_' fun h m (checkSeekableHandle act)
250 checkSeekableHandle act handle_ =
251 case haType handle_ of
252 ClosedHandle -> ioe_closedHandle
253 SemiClosedHandle -> ioe_closedHandle
254 AppendHandle -> ioe_notSeekable
255 _ | haIsBin handle_ || tEXT_MODE_SEEK_ALLOWED -> act handle_
256 | otherwise -> ioe_notSeekable_notBin
258 -- -----------------------------------------------------------------------------
261 ioe_closedHandle, ioe_EOF,
262 ioe_notReadable, ioe_notWritable,
263 ioe_notSeekable, ioe_notSeekable_notBin :: IO a
265 ioe_closedHandle = ioException
266 (IOError Nothing IllegalOperation ""
267 "handle is closed" Nothing)
268 ioe_EOF = ioException
269 (IOError Nothing EOF "" "" Nothing)
270 ioe_notReadable = ioException
271 (IOError Nothing IllegalOperation ""
272 "handle is not open for reading" Nothing)
273 ioe_notWritable = ioException
274 (IOError Nothing IllegalOperation ""
275 "handle is not open for writing" Nothing)
276 ioe_notSeekable = ioException
277 (IOError Nothing IllegalOperation ""
278 "handle is not seekable" Nothing)
279 ioe_notSeekable_notBin = ioException
280 (IOError Nothing IllegalOperation ""
281 "seek operations on text-mode handles are not allowed on this platform"
284 ioe_bufsiz :: Int -> IO a
285 ioe_bufsiz n = ioException
286 (IOError Nothing InvalidArgument "hSetBuffering"
287 ("illegal buffer size " ++ showsPrec 9 n []) Nothing)
288 -- 9 => should be parens'ified.
290 -- -----------------------------------------------------------------------------
293 -- For a duplex handle, we arrange that the read side points to the write side
294 -- (and hence keeps it alive if the read side is alive). This is done by
295 -- having the haOtherSide field of the read side point to the read side.
296 -- The finalizer is then placed on the write side, and the handle only gets
297 -- finalized once, when both sides are no longer required.
299 stdHandleFinalizer :: MVar Handle__ -> IO ()
300 stdHandleFinalizer m = do
302 flushWriteBufferOnly h_
304 handleFinalizer :: MVar Handle__ -> IO ()
305 handleFinalizer m = do
308 -- hClose puts both the fd and the handle's type
309 -- into a closed state, so it's a bit excessive
310 -- to test for both here, but caution sometimes
313 case haType h_ of { ClosedHandle{} -> True; _ -> False }
314 fd = fromIntegral (haFD h_)
316 when (not alreadyClosed && fd /= -1) $ do
317 flushWriteBufferOnly h_
319 #ifdef mingw32_TARGET_OS
320 (closeFd (haIsStream h_) fd >> return ())
322 (c_close fd >> return ())
325 -- ---------------------------------------------------------------------------
326 -- Grimy buffer operations
329 checkBufferInvariants h_ = do
330 let ref = haBuffer h_
331 Buffer{ bufWPtr=w, bufRPtr=r, bufSize=size, bufState=state } <- readIORef ref
336 && ( r /= w || (r == 0 && w == 0) )
337 && ( state /= WriteBuffer || r == 0 )
338 && ( state /= WriteBuffer || w < size ) -- write buffer is never full
340 then error "buffer invariant violation"
343 checkBufferInvariants h_ = return ()
346 newEmptyBuffer :: RawBuffer -> BufferState -> Int -> Buffer
347 newEmptyBuffer b state size
348 = Buffer{ bufBuf=b, bufRPtr=0, bufWPtr=0, bufSize=size, bufState=state }
350 allocateBuffer :: Int -> BufferState -> IO Buffer
351 allocateBuffer sz@(I# size) state = IO $ \s ->
352 case newByteArray# size s of { (# s, b #) ->
353 (# s, newEmptyBuffer b state sz #) }
355 writeCharIntoBuffer :: RawBuffer -> Int -> Char -> IO Int
356 writeCharIntoBuffer slab (I# off) (C# c)
357 = IO $ \s -> case writeCharArray# slab off c s of
358 s -> (# s, I# (off +# 1#) #)
360 readCharFromBuffer :: RawBuffer -> Int -> IO (Char, Int)
361 readCharFromBuffer slab (I# off)
362 = IO $ \s -> case readCharArray# slab off s of
363 (# s, c #) -> (# s, (C# c, I# (off +# 1#)) #)
365 getBuffer :: FD -> BufferState -> IO (IORef Buffer, BufferMode)
366 getBuffer fd state = do
367 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE state
368 ioref <- newIORef buffer
372 | is_tty = LineBuffering
373 | otherwise = BlockBuffering Nothing
375 return (ioref, buffer_mode)
377 mkUnBuffer :: IO (IORef Buffer)
379 buffer <- allocateBuffer 1 ReadBuffer
382 -- flushWriteBufferOnly flushes the buffer iff it contains pending write data.
383 flushWriteBufferOnly :: Handle__ -> IO ()
384 flushWriteBufferOnly h_ = do
388 new_buf <- if bufferIsWritable buf
389 then flushWriteBuffer fd (haIsStream h_) buf
391 writeIORef ref new_buf
393 -- flushBuffer syncs the file with the buffer, including moving the
394 -- file pointer backwards in the case of a read buffer.
395 flushBuffer :: Handle__ -> IO ()
397 let ref = haBuffer h_
402 ReadBuffer -> flushReadBuffer (haFD h_) buf
403 WriteBuffer -> flushWriteBuffer (haFD h_) (haIsStream h_) buf
405 writeIORef ref flushed_buf
407 -- When flushing a read buffer, we seek backwards by the number of
408 -- characters in the buffer. The file descriptor must therefore be
409 -- seekable: attempting to flush the read buffer on an unseekable
410 -- handle is not allowed.
412 flushReadBuffer :: FD -> Buffer -> IO Buffer
413 flushReadBuffer fd buf
414 | bufferEmpty buf = return buf
416 let off = negate (bufWPtr buf - bufRPtr buf)
418 puts ("flushReadBuffer: new file offset = " ++ show off ++ "\n")
420 throwErrnoIfMinus1Retry "flushReadBuffer"
421 (c_lseek (fromIntegral fd) (fromIntegral off) sEEK_CUR)
422 return buf{ bufWPtr=0, bufRPtr=0 }
424 flushWriteBuffer :: FD -> Bool -> Buffer -> IO Buffer
425 flushWriteBuffer fd is_stream buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = do
428 puts ("flushWriteBuffer, fd=" ++ show fd ++ ", bytes=" ++ show bytes ++ "\n")
431 then return (buf{ bufRPtr=0, bufWPtr=0 })
433 res <- throwErrnoIfMinus1RetryMayBlock "flushWriteBuffer"
434 (write_off_ba (fromIntegral fd) is_stream b (fromIntegral r)
435 (fromIntegral bytes))
437 let res' = fromIntegral res
439 then flushWriteBuffer fd is_stream (buf{ bufRPtr = r + res' })
440 else return buf{ bufRPtr=0, bufWPtr=0 }
442 foreign import ccall unsafe "__hscore_PrelHandle_write"
443 write_off_ba :: CInt -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
445 foreign import ccall unsafe "__hscore_PrelHandle_write"
446 write_off :: CInt -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
448 fillReadBuffer :: FD -> Bool -> Bool -> Buffer -> IO Buffer
449 fillReadBuffer fd is_line is_stream
450 buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w, bufSize=size } =
451 -- buffer better be empty:
452 assert (r == 0 && w == 0) $ do
453 fillReadBufferLoop fd is_line is_stream buf b w size
455 -- For a line buffer, we just get the first chunk of data to arrive,
456 -- and don't wait for the whole buffer to be full (but we *do* wait
457 -- until some data arrives). This isn't really line buffering, but it
458 -- appears to be what GHC has done for a long time, and I suspect it
459 -- is more useful than line buffering in most cases.
461 fillReadBufferLoop fd is_line is_stream buf b w size = do
463 if bytes == 0 -- buffer full?
464 then return buf{ bufRPtr=0, bufWPtr=w }
467 puts ("fillReadBufferLoop: bytes = " ++ show bytes ++ "\n")
469 res <- throwErrnoIfMinus1RetryMayBlock "fillReadBuffer"
470 (read_off_ba fd is_stream b (fromIntegral w) (fromIntegral bytes))
472 let res' = fromIntegral res
474 puts ("fillReadBufferLoop: res' = " ++ show res' ++ "\n")
479 else return buf{ bufRPtr=0, bufWPtr=w }
480 else if res' < bytes && not is_line
481 then fillReadBufferLoop fd is_line is_stream buf b (w+res') size
482 else return buf{ bufRPtr=0, bufWPtr=w+res' }
484 foreign import ccall unsafe "__hscore_PrelHandle_read"
485 read_off_ba :: FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
487 foreign import ccall unsafe "__hscore_PrelHandle_read"
488 read_off :: FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
490 -- ---------------------------------------------------------------------------
493 -- Three handles are allocated during program initialisation. The first
494 -- two manage input or output from the Haskell program's standard input
495 -- or output channel respectively. The third manages output to the
496 -- standard error channel. These handles are initially open.
503 stdin = unsafePerformIO $ do
504 -- ToDo: acquire lock
505 setNonBlockingFD fd_stdin
506 (buf, bmode) <- getBuffer fd_stdin ReadBuffer
507 mkStdHandle fd_stdin "<stdin>" ReadHandle buf bmode
510 stdout = 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_stdout
515 (buf, bmode) <- getBuffer fd_stdout WriteBuffer
516 mkStdHandle fd_stdout "<stdout>" WriteHandle buf bmode
519 stderr = unsafePerformIO $ do
520 -- ToDo: acquire lock
521 -- We don't set non-blocking mode on stdout or sterr, because
522 -- some shells don't recover properly.
523 -- setNonBlockingFD fd_stderr
525 mkStdHandle fd_stderr "<stderr>" WriteHandle buf NoBuffering
527 -- ---------------------------------------------------------------------------
528 -- Opening and Closing Files
531 Computation `openFile file mode' allocates and returns a new, open
532 handle to manage the file `file'. It manages input if `mode'
533 is `ReadMode', output if `mode' is `WriteMode' or `AppendMode',
534 and both input and output if mode is `ReadWriteMode'.
536 If the file does not exist and it is opened for output, it should be
537 created as a new file. If `mode' is `WriteMode' and the file
538 already exists, then it should be truncated to zero length. The
539 handle is positioned at the end of the file if `mode' is
540 `AppendMode', and otherwise at the beginning (in which case its
541 internal position is 0).
543 Implementations should enforce, locally to the Haskell process,
544 multiple-reader single-writer locking on files, which is to say that
545 there may either be many handles on the same file which manage input,
546 or just one handle on the file which manages output. If any open or
547 semi-closed handle is managing a file for output, no new handle can be
548 allocated for that file. If any open or semi-closed handle is
549 managing a file for input, new handles can only be allocated if they
550 do not manage output.
552 Two files are the same if they have the same absolute name. An
553 implementation is free to impose stricter conditions.
559 deriving (Eq, Read, Show)
561 addFilePathToIOError fun fp (IOError h iot _ str _)
562 = IOError h iot fun str (Just fp)
564 openFile :: FilePath -> IOMode -> IO Handle
567 (openFile' fp (if dEFAULT_OPEN_IN_BINARY_MODE
570 (\e -> ioError (addFilePathToIOError "openFile" fp e))
572 openFileEx :: FilePath -> IOModeEx -> IO Handle
576 (\e -> ioError (addFilePathToIOError "openFileEx" fp e))
579 openFile' filepath ex_mode =
580 withCString filepath $ \ f ->
585 BinaryMode bmo -> (bmo, True)
586 TextMode tmo -> (tmo, False)
588 oflags1 = case mode of
589 ReadMode -> read_flags
590 WriteMode -> write_flags
591 ReadWriteMode -> rw_flags
592 AppendMode -> append_flags
594 truncate | WriteMode <- mode = True
601 oflags = oflags1 .|. binary_flags
604 -- the old implementation had a complicated series of three opens,
605 -- which is perhaps because we have to be careful not to open
606 -- directories. However, the man pages I've read say that open()
607 -- always returns EISDIR if the file is a directory and was opened
608 -- for writing, so I think we're ok with a single open() here...
609 fd <- fromIntegral `liftM`
610 throwErrnoIfMinus1Retry "openFile"
611 (c_open f (fromIntegral oflags) 0o666)
613 openFd fd Nothing filepath mode binary truncate
614 -- ASSERT: if we just created the file, then openFd won't fail
615 -- (so we don't need to worry about removing the newly created file
616 -- in the event of an error).
619 std_flags = o_NONBLOCK .|. o_NOCTTY
620 output_flags = std_flags .|. o_CREAT
621 read_flags = std_flags .|. o_RDONLY
622 write_flags = output_flags .|. o_WRONLY
623 rw_flags = output_flags .|. o_RDWR
624 append_flags = write_flags .|. o_APPEND
626 -- ---------------------------------------------------------------------------
629 openFd :: FD -> Maybe FDType -> FilePath -> IOMode -> Bool -> Bool -> IO Handle
630 openFd fd mb_fd_type filepath mode binary truncate = do
631 -- turn on non-blocking mode
634 let (ha_type, write) =
636 ReadMode -> ( ReadHandle, False )
637 WriteMode -> ( WriteHandle, True )
638 ReadWriteMode -> ( ReadWriteHandle, True )
639 AppendMode -> ( AppendHandle, True )
641 -- open() won't tell us if it was a directory if we only opened for
642 -- reading, so check again.
647 let is_stream = fd_type == Stream
650 ioException (IOError Nothing InappropriateType "openFile"
651 "is a directory" Nothing)
654 | ReadWriteHandle <- ha_type -> mkDuplexHandle fd is_stream filepath binary
655 | otherwise -> mkFileHandle fd is_stream filepath ha_type binary
657 -- regular files need to be locked
659 r <- lockFile (fromIntegral fd) (fromBool write) 1{-exclusive-}
661 ioException (IOError Nothing ResourceBusy "openFile"
662 "file is locked" Nothing)
664 -- truncate the file if necessary
665 when truncate (fileTruncate filepath)
667 mkFileHandle fd is_stream filepath ha_type binary
670 fdToHandle :: FD -> IO Handle
673 let fd_str = "<file descriptor: " ++ show fd ++ ">"
674 openFd fd Nothing fd_str mode True{-bin mode-} False{-no truncate-}
676 foreign import ccall unsafe "lockFile"
677 lockFile :: CInt -> CInt -> CInt -> IO CInt
679 foreign import ccall unsafe "unlockFile"
680 unlockFile :: CInt -> IO CInt
682 mkStdHandle :: FD -> FilePath -> HandleType -> IORef Buffer -> BufferMode
684 mkStdHandle fd filepath ha_type buf bmode = do
685 spares <- newIORef BufferListNil
686 newFileHandle stdHandleFinalizer
687 (Handle__ { haFD = fd,
689 haIsBin = dEFAULT_OPEN_IN_BINARY_MODE,
691 haBufferMode = bmode,
692 haFilePath = filepath,
695 haOtherSide = Nothing
698 mkFileHandle :: FD -> Bool -> FilePath -> HandleType -> Bool -> IO Handle
699 mkFileHandle fd is_stream filepath ha_type binary = do
700 (buf, bmode) <- getBuffer fd (initBufferState ha_type)
701 spares <- newIORef BufferListNil
702 newFileHandle handleFinalizer
703 (Handle__ { haFD = fd,
706 haIsStream = is_stream,
707 haBufferMode = bmode,
708 haFilePath = filepath,
711 haOtherSide = Nothing
714 mkDuplexHandle :: FD -> Bool -> FilePath -> Bool -> IO Handle
715 mkDuplexHandle fd is_stream filepath binary = do
716 (w_buf, w_bmode) <- getBuffer fd WriteBuffer
717 w_spares <- newIORef BufferListNil
719 Handle__ { haFD = fd,
720 haType = WriteHandle,
722 haIsStream = is_stream,
723 haBufferMode = w_bmode,
724 haFilePath = filepath,
726 haBuffers = w_spares,
727 haOtherSide = Nothing
729 write_side <- newMVar w_handle_
731 (r_buf, r_bmode) <- getBuffer fd ReadBuffer
732 r_spares <- newIORef BufferListNil
734 Handle__ { haFD = fd,
737 haIsStream = is_stream,
738 haBufferMode = r_bmode,
739 haFilePath = filepath,
741 haBuffers = r_spares,
742 haOtherSide = Just write_side
744 read_side <- newMVar r_handle_
746 addMVarFinalizer read_side (handleFinalizer read_side)
747 return (DuplexHandle read_side write_side)
750 initBufferState ReadHandle = ReadBuffer
751 initBufferState _ = WriteBuffer
753 -- ---------------------------------------------------------------------------
756 -- Computation `hClose hdl' makes handle `hdl' closed. Before the
757 -- computation finishes, any items buffered for output and not already
758 -- sent to the operating system are flushed as for `hFlush'.
760 -- For a duplex handle, we close&flush the write side, and just close
763 hClose :: Handle -> IO ()
764 hClose h@(FileHandle m) = hClose' h m
765 hClose h@(DuplexHandle r w) = hClose' h w >> hClose' h r
767 hClose' h m = withHandle__' "hClose" h m $ hClose_help
769 -- hClose_help is also called by lazyRead (in PrelIO) when EOF is read
770 -- or an IO error occurs on a lazy stream. The semi-closed Handle is
771 -- then closed immediately. We have to be careful with DuplexHandles
772 -- though: we have to leave the closing to the finalizer in that case,
773 -- because the write side may still be in use.
774 hClose_help :: Handle__ -> IO Handle__
775 hClose_help handle_ =
776 case haType handle_ of
777 ClosedHandle -> return handle_
779 let fd = haFD handle_
780 c_fd = fromIntegral fd
782 flushWriteBufferOnly handle_
784 -- close the file descriptor, but not when this is the read
785 -- side of a duplex handle, and not when this is one of the
787 case haOtherSide handle_ of
789 when (fd /= fd_stdin && fd /= fd_stdout && fd /= fd_stderr) $
790 throwErrnoIfMinus1Retry_ "hClose"
791 #ifdef mingw32_TARGET_OS
792 (closeFd (haIsStream handle_) c_fd)
798 -- free the spare buffers
799 writeIORef (haBuffers handle_) BufferListNil
804 -- we must set the fd to -1, because the finalizer is going
805 -- to run eventually and try to close/unlock it.
806 return (handle_{ haFD = -1,
807 haType = ClosedHandle
810 -----------------------------------------------------------------------------
811 -- Detecting the size of a file
813 -- For a handle `hdl' which attached to a physical file, `hFileSize
814 -- hdl' returns the size of `hdl' in terms of the number of items
815 -- which can be read from `hdl'.
817 hFileSize :: Handle -> IO Integer
819 withHandle_ "hFileSize" handle $ \ handle_ -> do
820 case haType handle_ of
821 ClosedHandle -> ioe_closedHandle
822 SemiClosedHandle -> ioe_closedHandle
823 _ -> do flushWriteBufferOnly handle_
824 r <- fdFileSize (haFD handle_)
827 else ioException (IOError Nothing InappropriateType "hFileSize"
828 "not a regular file" Nothing)
830 -- ---------------------------------------------------------------------------
831 -- Detecting the End of Input
833 -- For a readable handle `hdl', `hIsEOF hdl' returns
834 -- `True' if no further input can be taken from `hdl' or for a
835 -- physical file, if the current I/O position is equal to the length of
836 -- the file. Otherwise, it returns `False'.
838 hIsEOF :: Handle -> IO Bool
841 (do hLookAhead handle; return False)
842 (\e -> if isEOFError e then return True else ioError e)
847 -- ---------------------------------------------------------------------------
850 -- hLookahead returns the next character from the handle without
851 -- removing it from the input buffer, blocking until a character is
854 hLookAhead :: Handle -> IO Char
855 hLookAhead handle = do
856 wantReadableHandle "hLookAhead" handle $ \handle_ -> do
857 let ref = haBuffer handle_
859 is_line = haBufferMode handle_ == LineBuffering
862 -- fill up the read buffer if necessary
863 new_buf <- if bufferEmpty buf
864 then fillReadBuffer fd is_line (haIsStream handle_) buf
867 writeIORef ref new_buf
869 (c,_) <- readCharFromBuffer (bufBuf buf) (bufRPtr buf)
872 -- ---------------------------------------------------------------------------
873 -- Buffering Operations
875 -- Three kinds of buffering are supported: line-buffering,
876 -- block-buffering or no-buffering. See GHC.IOBase for definition and
877 -- further explanation of what the type represent.
879 -- Computation `hSetBuffering hdl mode' sets the mode of buffering for
880 -- handle hdl on subsequent reads and writes.
882 -- * If mode is LineBuffering, line-buffering should be enabled if possible.
884 -- * If mode is `BlockBuffering size', then block-buffering
885 -- should be enabled if possible. The size of the buffer is n items
886 -- if size is `Just n' and is otherwise implementation-dependent.
888 -- * If mode is NoBuffering, then buffering is disabled if possible.
890 -- If the buffer mode is changed from BlockBuffering or
891 -- LineBuffering to NoBuffering, then any items in the output
892 -- buffer are written to the device, and any items in the input buffer
893 -- are discarded. The default buffering mode when a handle is opened
894 -- is implementation-dependent and may depend on the object which is
895 -- attached to that handle.
897 hSetBuffering :: Handle -> BufferMode -> IO ()
898 hSetBuffering handle mode =
899 withAllHandles__ "hSetBuffering" handle $ \ handle_ -> do
900 case haType handle_ of
901 ClosedHandle -> ioe_closedHandle
904 - we flush the old buffer regardless of whether
905 the new buffer could fit the contents of the old buffer
907 - allow a handle's buffering to change even if IO has
908 occurred (ANSI C spec. does not allow this, nor did
909 the previous implementation of IO.hSetBuffering).
910 - a non-standard extension is to allow the buffering
911 of semi-closed handles to change [sof 6/98]
915 let state = initBufferState (haType handle_)
918 -- we always have a 1-character read buffer for
919 -- unbuffered handles: it's needed to
920 -- support hLookAhead.
921 NoBuffering -> allocateBuffer 1 ReadBuffer
922 LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state
923 BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state
924 BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n
925 | otherwise -> allocateBuffer n state
926 writeIORef (haBuffer handle_) new_buf
928 -- for input terminals we need to put the terminal into
929 -- cooked or raw mode depending on the type of buffering.
930 is_tty <- fdIsTTY (haFD handle_)
931 when (is_tty && isReadableHandleType (haType handle_)) $
933 NoBuffering -> setCooked (haFD handle_) False
934 _ -> setCooked (haFD handle_) True
936 -- throw away spare buffers, they might be the wrong size
937 writeIORef (haBuffers handle_) BufferListNil
939 return (handle_{ haBufferMode = mode })
941 -- -----------------------------------------------------------------------------
944 -- The action `hFlush hdl' causes any items buffered for output
945 -- in handle `hdl' to be sent immediately to the operating
948 hFlush :: Handle -> IO ()
950 wantWritableHandle "hFlush" handle $ \ handle_ -> do
951 buf <- readIORef (haBuffer handle_)
952 if bufferIsWritable buf && not (bufferEmpty buf)
953 then do flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf
954 writeIORef (haBuffer handle_) flushed_buf
958 -- -----------------------------------------------------------------------------
959 -- Repositioning Handles
961 data HandlePosn = HandlePosn Handle HandlePosition
963 instance Eq HandlePosn where
964 (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2
966 instance Show HandlePosn where
967 showsPrec p (HandlePosn h pos) =
968 showsPrec p h . showString " at position " . shows pos
970 -- HandlePosition is the Haskell equivalent of POSIX' off_t.
971 -- We represent it as an Integer on the Haskell side, but
972 -- cheat slightly in that hGetPosn calls upon a C helper
973 -- that reports the position back via (merely) an Int.
974 type HandlePosition = Integer
976 -- Computation `hGetPosn hdl' returns the current I/O position of
977 -- `hdl' as an abstract position. Computation `hSetPosn p' sets the
978 -- position of `hdl' to a previously obtained position `p'.
980 hGetPosn :: Handle -> IO HandlePosn
983 return (HandlePosn handle posn)
985 hSetPosn :: HandlePosn -> IO ()
986 hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i
988 -- ---------------------------------------------------------------------------
992 The action `hSeek hdl mode i' sets the position of handle
993 `hdl' depending on `mode'. If `mode' is
995 * AbsoluteSeek - The position of `hdl' is set to `i'.
996 * RelativeSeek - The position of `hdl' is set to offset `i' from
997 the current position.
998 * SeekFromEnd - The position of `hdl' is set to offset `i' from
1001 Some handles may not be seekable (see `hIsSeekable'), or only
1002 support a subset of the possible positioning operations (e.g. it may
1003 only be possible to seek to the end of a tape, or to a positive
1004 offset from the beginning or current position).
1006 It is not possible to set a negative I/O position, or for a physical
1007 file, an I/O position beyond the current end-of-file.
1010 - when seeking using `SeekFromEnd', positive offsets (>=0) means
1011 seeking at or past EOF.
1013 - we possibly deviate from the report on the issue of seeking within
1014 the buffer and whether to flush it or not. The report isn't exactly
1018 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
1019 deriving (Eq, Ord, Ix, Enum, Read, Show)
1021 hSeek :: Handle -> SeekMode -> Integer -> IO ()
1022 hSeek handle mode offset =
1023 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
1025 puts ("hSeek " ++ show (mode,offset) ++ "\n")
1027 let ref = haBuffer handle_
1028 buf <- readIORef ref
1034 throwErrnoIfMinus1Retry_ "hSeek"
1035 (c_lseek (fromIntegral (haFD handle_)) (fromIntegral offset) whence)
1038 whence = case mode of
1039 AbsoluteSeek -> sEEK_SET
1040 RelativeSeek -> sEEK_CUR
1041 SeekFromEnd -> sEEK_END
1043 if bufferIsWritable buf
1044 then do new_buf <- flushWriteBuffer fd (haIsStream handle_) buf
1045 writeIORef ref new_buf
1049 if mode == RelativeSeek && offset >= 0 && offset < fromIntegral (w - r)
1050 then writeIORef ref buf{ bufRPtr = r + fromIntegral offset }
1053 new_buf <- flushReadBuffer (haFD handle_) buf
1054 writeIORef ref new_buf
1058 hTell :: Handle -> IO Integer
1060 wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
1062 #if defined(mingw32_TARGET_OS)
1063 -- urgh, on Windows we have to worry about \n -> \r\n translation,
1064 -- so we can't easily calculate the file position using the
1065 -- current buffer size. Just flush instead.
1068 let fd = fromIntegral (haFD handle_)
1069 posn <- fromIntegral `liftM`
1070 throwErrnoIfMinus1Retry "hGetPosn"
1071 (c_lseek fd 0 sEEK_CUR)
1073 let ref = haBuffer handle_
1074 buf <- readIORef ref
1077 | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf)
1078 | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf)
1080 puts ("\nhGetPosn: (fd, posn, real_posn) = " ++ show (fd, posn, real_posn) ++ "\n")
1081 puts (" (bufWPtr, bufRPtr) = " ++ show (bufWPtr buf, bufRPtr buf) ++ "\n")
1085 -- -----------------------------------------------------------------------------
1086 -- Handle Properties
1088 -- A number of operations return information about the properties of a
1089 -- handle. Each of these operations returns `True' if the handle has
1090 -- the specified property, and `False' otherwise.
1092 hIsOpen :: Handle -> IO Bool
1094 withHandle_ "hIsOpen" handle $ \ handle_ -> do
1095 case haType handle_ of
1096 ClosedHandle -> return False
1097 SemiClosedHandle -> return False
1100 hIsClosed :: Handle -> IO Bool
1102 withHandle_ "hIsClosed" handle $ \ handle_ -> do
1103 case haType handle_ of
1104 ClosedHandle -> return True
1107 {- not defined, nor exported, but mentioned
1108 here for documentation purposes:
1110 hSemiClosed :: Handle -> IO Bool
1114 return (not (ho || hc))
1117 hIsReadable :: Handle -> IO Bool
1118 hIsReadable (DuplexHandle _ _) = return True
1119 hIsReadable handle =
1120 withHandle_ "hIsReadable" handle $ \ handle_ -> do
1121 case haType handle_ of
1122 ClosedHandle -> ioe_closedHandle
1123 SemiClosedHandle -> ioe_closedHandle
1124 htype -> return (isReadableHandleType htype)
1126 hIsWritable :: Handle -> IO Bool
1127 hIsWritable (DuplexHandle _ _) = return False
1128 hIsWritable handle =
1129 withHandle_ "hIsWritable" handle $ \ handle_ -> do
1130 case haType handle_ of
1131 ClosedHandle -> ioe_closedHandle
1132 SemiClosedHandle -> ioe_closedHandle
1133 htype -> return (isWritableHandleType htype)
1135 -- Querying how a handle buffers its data:
1137 hGetBuffering :: Handle -> IO BufferMode
1138 hGetBuffering handle =
1139 withHandle_ "hGetBuffering" handle $ \ handle_ -> do
1140 case haType handle_ of
1141 ClosedHandle -> ioe_closedHandle
1143 -- We're being non-standard here, and allow the buffering
1144 -- of a semi-closed handle to be queried. -- sof 6/98
1145 return (haBufferMode handle_) -- could be stricter..
1147 hIsSeekable :: Handle -> IO Bool
1148 hIsSeekable handle =
1149 withHandle_ "hIsSeekable" handle $ \ handle_ -> do
1150 case haType handle_ of
1151 ClosedHandle -> ioe_closedHandle
1152 SemiClosedHandle -> ioe_closedHandle
1153 AppendHandle -> return False
1154 _ -> do t <- fdType (haFD handle_)
1155 return (t == RegularFile
1157 || tEXT_MODE_SEEK_ALLOWED))
1159 -- -----------------------------------------------------------------------------
1160 -- Changing echo status
1162 -- Non-standard GHC extension is to allow the echoing status
1163 -- of a handles connected to terminals to be reconfigured:
1165 hSetEcho :: Handle -> Bool -> IO ()
1166 hSetEcho handle on = do
1167 isT <- hIsTerminalDevice handle
1171 withHandle_ "hSetEcho" handle $ \ handle_ -> do
1172 case haType handle_ of
1173 ClosedHandle -> ioe_closedHandle
1174 _ -> setEcho (haFD handle_) on
1176 hGetEcho :: Handle -> IO Bool
1177 hGetEcho handle = do
1178 isT <- hIsTerminalDevice handle
1182 withHandle_ "hGetEcho" handle $ \ handle_ -> do
1183 case haType handle_ of
1184 ClosedHandle -> ioe_closedHandle
1185 _ -> getEcho (haFD handle_)
1187 hIsTerminalDevice :: Handle -> IO Bool
1188 hIsTerminalDevice handle = do
1189 withHandle_ "hIsTerminalDevice" handle $ \ handle_ -> do
1190 case haType handle_ of
1191 ClosedHandle -> ioe_closedHandle
1192 _ -> fdIsTTY (haFD handle_)
1194 -- -----------------------------------------------------------------------------
1197 -- | On Windows, reading a file in text mode (which is the default) will
1198 -- translate CRLF to LF, and writing will translate LF to CRLF. This
1199 -- is usually what you want with text files. With binary files this is
1200 -- undesirable; also, as usual under Microsoft operating systems, text
1201 -- mode treats control-Z as EOF. Setting binary mode using
1202 -- 'hSetBinaryMode' turns off all special treatment of end-of-line and
1203 -- end-of-file characters.
1205 hSetBinaryMode :: Handle -> Bool -> IO ()
1206 hSetBinaryMode handle bin =
1207 withAllHandles__ "hSetBinaryMode" handle $ \ handle_ ->
1208 do throwErrnoIfMinus1_ "hSetBinaryMode"
1209 (setmode (fromIntegral (haFD handle_)) bin)
1210 return handle_{haIsBin=bin}
1212 foreign import ccall unsafe "__hscore_setmode"
1213 setmode :: CInt -> Bool -> IO CInt
1215 -- -----------------------------------------------------------------------------
1216 -- Duplicating a Handle
1218 -- |Returns a duplicate of the original handle, with its own buffer
1219 -- and file pointer. The original handle's buffer is flushed, including
1220 -- discarding any input data, before the handle is duplicated.
1222 hDuplicate :: Handle -> IO Handle
1223 hDuplicate h@(FileHandle m) = do
1224 new_h_ <- withHandle' "hDuplicate" h m (dupHandle_ Nothing)
1225 new_m <- newMVar new_h_
1226 return (FileHandle new_m)
1227 hDuplicate h@(DuplexHandle r w) = do
1228 new_w_ <- withHandle' "hDuplicate" h w (dupHandle_ Nothing)
1229 new_w <- newMVar new_w_
1230 new_r_ <- withHandle' "hDuplicate" h r (dupHandle_ (Just new_w))
1231 new_r <- newMVar new_r_
1232 return (DuplexHandle new_r new_w)
1234 dupHandle_ other_side h_ = do
1235 -- flush the buffer first, so we don't have to copy its contents
1237 new_fd <- c_dup (fromIntegral (haFD h_))
1238 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE (initBufferState (haType h_))
1239 ioref <- newIORef buffer
1240 ioref_buffers <- newIORef BufferListNil
1242 let new_handle_ = h_{ haFD = fromIntegral new_fd,
1244 haBuffers = ioref_buffers,
1245 haOtherSide = other_side }
1246 return (h_, new_handle_)
1248 -- -----------------------------------------------------------------------------
1249 -- Replacing a Handle
1252 Makes the second handle a duplicate of the first handle. The second
1253 handle will be closed first, if it is not already.
1255 This can be used to retarget the standard Handles, for example:
1257 > do h <- openFile "mystdout" WriteMode
1258 > hDuplicateTo h stdout
1261 hDuplicateTo :: Handle -> Handle -> IO ()
1262 hDuplicateTo h1@(FileHandle m1) h2@(FileHandle m2) = do
1263 withHandle__' "hDuplicateTo" h2 m2 $ \h2_ -> do
1264 _ <- hClose_help h2_
1265 withHandle' "hDuplicateTo" h1 m1 (dupHandle_ Nothing)
1266 hDuplicateTo h1@(DuplexHandle r1 w1) h2@(DuplexHandle r2 w2) = do
1267 withHandle__' "hDuplicateTo" h2 w2 $ \w2_ -> do
1268 _ <- hClose_help w2_
1269 withHandle' "hDuplicateTo" h1 r1 (dupHandle_ Nothing)
1270 withHandle__' "hDuplicateTo" h2 r2 $ \r2_ -> do
1271 _ <- hClose_help r2_
1272 withHandle' "hDuplicateTo" h1 r1 (dupHandle_ (Just w1))
1274 ioException (IOError (Just h1) IllegalOperation "hDuplicateTo"
1275 "handles are incompatible" Nothing)
1277 -- ---------------------------------------------------------------------------
1281 puts :: String -> IO ()
1282 puts s = withCString s $ \cstr -> do write_off_ba 1 False cstr 0 (fromIntegral (length s))
1286 -- -----------------------------------------------------------------------------
1287 -- wrappers to platform-specific constants:
1289 foreign import ccall unsafe "__hscore_supportsTextMode"
1290 tEXT_MODE_SEEK_ALLOWED :: Bool
1292 foreign import ccall unsafe "__hscore_bufsiz" dEFAULT_BUFFER_SIZE :: Int
1293 foreign import ccall unsafe "__hscore_seek_cur" sEEK_CUR :: CInt
1294 foreign import ccall unsafe "__hscore_seek_set" sEEK_SET :: CInt
1295 foreign import ccall unsafe "__hscore_seek_end" sEEK_END :: CInt