1 {-# OPTIONS -fno-implicit-prelude #-}
6 -- -----------------------------------------------------------------------------
7 -- $Id: PrelHandle.hsc,v 1.8 2001/06/01 13:06:01 sewardj 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 -- Are files opened by default in text or binary mode, if the user doesn't
81 dEFAULT_OPEN_IN_BINARY_MODE :: Bool
82 dEFAULT_OPEN_IN_BINARY_MODE = False
84 -- ---------------------------------------------------------------------------
85 -- Creating a new handle
87 newFileHandle :: (MVar Handle__ -> IO ()) -> Handle__ -> IO Handle
88 newFileHandle finalizer hc = do
90 addMVarFinalizer m (finalizer m)
93 -- ---------------------------------------------------------------------------
94 -- Working with Handles
97 In the concurrent world, handles are locked during use. This is done
98 by wrapping an MVar around the handle which acts as a mutex over
99 operations on the handle.
101 To avoid races, we use the following bracketing operations. The idea
102 is to obtain the lock, do some operation and replace the lock again,
103 whether the operation succeeded or failed. We also want to handle the
104 case where the thread receives an exception while processing the IO
105 operation: in these cases we also want to relinquish the lock.
107 There are three versions of @withHandle@: corresponding to the three
108 possible combinations of:
110 - the operation may side-effect the handle
111 - the operation may return a result
113 If the operation generates an error or an exception is raised, the
114 original handle is always replaced [ this is the case at the moment,
115 but we might want to revisit this in the future --SDM ].
118 {-# INLINE withHandle #-}
119 withHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
120 withHandle fun h@(FileHandle m) act = withHandle' fun h m act
121 withHandle fun h@(DuplexHandle r w) act = do
122 withHandle' fun h r act
123 withHandle' fun h w act
125 withHandle' fun h m act =
128 checkBufferInvariants h_
129 (h',v) <- catchException (act h_)
130 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
131 checkBufferInvariants h'
135 {-# INLINE withHandle_ #-}
136 withHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
137 withHandle_ fun h@(FileHandle m) act = withHandle_' fun h m act
138 withHandle_ fun h@(DuplexHandle m _) act = withHandle_' fun h m act
140 withHandle_' fun h m act =
143 checkBufferInvariants h_
144 v <- catchException (act h_)
145 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
146 checkBufferInvariants h_
150 withAllHandles__ :: String -> Handle -> (Handle__ -> IO Handle__) -> IO ()
151 withAllHandles__ fun h@(FileHandle m) act = withHandle__' fun h m act
152 withAllHandles__ fun h@(DuplexHandle r w) act = do
153 withHandle__' fun h r act
154 withHandle__' fun h w act
156 withHandle__' fun h m act =
159 checkBufferInvariants h_
160 h' <- catchException (act h_)
161 (\ ex -> putMVar m h_ >> throw (augmentIOError ex fun h h_))
162 checkBufferInvariants h'
166 augmentIOError (IOException (IOError _ iot _ str fp)) fun h h_
167 = IOException (IOError (Just h) iot fun str filepath)
168 where filepath | Just _ <- fp = fp
169 | otherwise = Just (haFilePath h_)
170 augmentIOError other_exception _ _ _
173 -- ---------------------------------------------------------------------------
174 -- Wrapper for write operations.
176 wantWritableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
177 wantWritableHandle fun h@(FileHandle m) act
178 = wantWritableHandle' fun h m act
179 wantWritableHandle fun h@(DuplexHandle _ m) act
180 = wantWritableHandle' fun h m act
181 -- ToDo: in the Duplex case, we don't need to checkWritableHandle
184 :: String -> Handle -> MVar Handle__
185 -> (Handle__ -> IO a) -> IO a
186 wantWritableHandle' fun h m act
187 = withHandle_' fun h m (checkWritableHandle act)
189 checkWritableHandle act handle_
190 = case haType handle_ of
191 ClosedHandle -> ioe_closedHandle
192 SemiClosedHandle -> ioe_closedHandle
193 ReadHandle -> ioe_notWritable
194 ReadWriteHandle -> do
195 let ref = haBuffer handle_
198 if not (bufferIsWritable buf)
199 then do b <- flushReadBuffer (haFD handle_) buf
200 return b{ bufState=WriteBuffer }
202 writeIORef ref new_buf
204 _other -> act handle_
206 -- ---------------------------------------------------------------------------
207 -- Wrapper for read operations.
209 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
210 wantReadableHandle fun h@(FileHandle m) act
211 = wantReadableHandle' fun h m act
212 wantReadableHandle fun h@(DuplexHandle m _) act
213 = wantReadableHandle' fun h m act
214 -- ToDo: in the Duplex case, we don't need to checkReadableHandle
217 :: String -> Handle -> MVar Handle__
218 -> (Handle__ -> IO a) -> IO a
219 wantReadableHandle' fun h m act
220 = withHandle_' fun h m (checkReadableHandle act)
222 checkReadableHandle act handle_ =
223 case haType handle_ of
224 ClosedHandle -> ioe_closedHandle
225 SemiClosedHandle -> ioe_closedHandle
226 AppendHandle -> ioe_notReadable
227 WriteHandle -> ioe_notReadable
228 ReadWriteHandle -> do
229 let ref = haBuffer handle_
231 when (bufferIsWritable buf) $ do
232 new_buf <- flushWriteBuffer (haFD handle_) buf
233 writeIORef ref new_buf{ bufState=ReadBuffer }
235 _other -> act handle_
237 -- ---------------------------------------------------------------------------
238 -- Wrapper for seek operations.
240 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
241 wantSeekableHandle fun h@(DuplexHandle _ _) _act =
242 ioException (IOError (Just h) IllegalOperation fun
243 "handle is not seekable" Nothing)
244 wantSeekableHandle fun h@(FileHandle m) act =
245 withHandle_' fun h m (checkSeekableHandle act)
247 checkSeekableHandle act handle_ =
248 case haType handle_ of
249 ClosedHandle -> ioe_closedHandle
250 SemiClosedHandle -> ioe_closedHandle
251 AppendHandle -> ioe_notSeekable
252 _ | haIsBin handle_ -> act handle_
253 | otherwise -> ioe_notSeekable_notBin
255 -- -----------------------------------------------------------------------------
258 ioe_closedHandle, ioe_EOF,
259 ioe_notReadable, ioe_notWritable,
260 ioe_notSeekable, ioe_notSeekable_notBin :: IO a
262 ioe_closedHandle = ioException
263 (IOError Nothing IllegalOperation ""
264 "handle is closed" Nothing)
265 ioe_EOF = ioException
266 (IOError Nothing EOF "" "" Nothing)
267 ioe_notReadable = ioException
268 (IOError Nothing IllegalOperation ""
269 "handle is not open for reading" Nothing)
270 ioe_notWritable = ioException
271 (IOError Nothing IllegalOperation ""
272 "handle is not open for writing" Nothing)
273 ioe_notSeekable = ioException
274 (IOError Nothing IllegalOperation ""
275 "handle is not seekable" Nothing)
276 ioe_notSeekable_notBin = ioException
277 (IOError Nothing IllegalOperation ""
278 "seek operations are only allowed on binary-mode handles" Nothing)
280 ioe_bufsiz :: Int -> IO a
281 ioe_bufsiz n = ioException
282 (IOError Nothing InvalidArgument "hSetBuffering"
283 ("illegal buffer size " ++ showsPrec 9 n []) Nothing)
284 -- 9 => should be parens'ified.
286 -- -----------------------------------------------------------------------------
289 -- For a duplex handle, we arrange that the read side points to the write side
290 -- (and hence keeps it alive if the read side is alive). This is done by
291 -- having the haType field of the read side be ReadSideHandle with a pointer
292 -- to the write side. The finalizer is then placed on the write side, and
293 -- the handle only gets finalized once, when both sides are no longer
296 addFinalizer :: Handle -> IO ()
297 addFinalizer (FileHandle m) = addMVarFinalizer m (handleFinalizer m)
298 addFinalizer (DuplexHandle _ w) = addMVarFinalizer w (handleFinalizer w)
300 stdHandleFinalizer :: MVar Handle__ -> IO ()
301 stdHandleFinalizer m = do
303 flushWriteBufferOnly h_
305 handleFinalizer :: MVar Handle__ -> IO ()
306 handleFinalizer m = do
308 flushWriteBufferOnly h_
309 let fd = fromIntegral (haFD h_)
311 -- ToDo: closesocket() for a WINSOCK socket?
312 when (fd /= -1) (c_close fd >> return ())
315 -- ---------------------------------------------------------------------------
316 -- Grimy buffer operations
319 checkBufferInvariants h_ = do
320 let ref = haBuffer h_
321 Buffer{ bufWPtr=w, bufRPtr=r, bufSize=size, bufState=state } <- readIORef ref
326 && ( r /= w || (r == 0 && w == 0) )
327 && ( state /= WriteBuffer || r == 0 )
328 && ( state /= WriteBuffer || w < size ) -- write buffer is never full
330 then error "buffer invariant violation"
333 checkBufferInvariants h_ = return ()
336 newEmptyBuffer :: RawBuffer -> BufferState -> Int -> Buffer
337 newEmptyBuffer b state size
338 = Buffer{ bufBuf=b, bufRPtr=0, bufWPtr=0, bufSize=size, bufState=state }
340 allocateBuffer :: Int -> BufferState -> IO Buffer
341 allocateBuffer sz@(I## size) state = IO $ \s ->
342 case newByteArray## size s of { (## s, b ##) ->
343 (## s, newEmptyBuffer b state sz ##) }
345 writeCharIntoBuffer :: RawBuffer -> Int -> Char -> IO Int
346 writeCharIntoBuffer slab (I## off) (C## c)
347 = IO $ \s -> case writeCharArray## slab off c s of
348 s -> (## s, I## (off +## 1##) ##)
350 readCharFromBuffer :: RawBuffer -> Int -> IO (Char, Int)
351 readCharFromBuffer slab (I## off)
352 = IO $ \s -> case readCharArray## slab off s of
353 (## s, c ##) -> (## s, (C## c, I## (off +## 1##)) ##)
355 dEFAULT_BUFFER_SIZE = (#const BUFSIZ) :: Int
357 getBuffer :: FD -> BufferState -> IO (IORef Buffer, BufferMode)
358 getBuffer fd state = do
359 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE state
360 ioref <- newIORef buffer
364 | is_tty = LineBuffering
365 | otherwise = BlockBuffering Nothing
367 return (ioref, buffer_mode)
369 mkUnBuffer :: IO (IORef Buffer)
371 buffer <- allocateBuffer 1 ReadBuffer
374 -- flushWriteBufferOnly flushes the buffer iff it contains pending write data.
375 flushWriteBufferOnly :: Handle__ -> IO ()
376 flushWriteBufferOnly h_ = do
380 new_buf <- if bufferIsWritable buf
381 then flushWriteBuffer fd buf
383 writeIORef ref new_buf
385 -- flushBuffer syncs the file with the buffer, including moving the
386 -- file pointer backwards in the case of a read buffer.
387 flushBuffer :: Handle__ -> IO ()
389 let ref = haBuffer h_
394 ReadBuffer -> flushReadBuffer (haFD h_) buf
395 WriteBuffer -> flushWriteBuffer (haFD h_) buf
397 writeIORef ref flushed_buf
399 -- When flushing a read buffer, we seek backwards by the number of
400 -- characters in the buffer. The file descriptor must therefore be
401 -- seekable: attempting to flush the read buffer on an unseekable
402 -- handle is not allowed.
404 flushReadBuffer :: FD -> Buffer -> IO Buffer
405 flushReadBuffer fd buf
406 | bufferEmpty buf = return buf
408 let off = negate (bufWPtr buf - bufRPtr buf)
410 puts ("flushReadBuffer: new file offset = " ++ show off ++ "\n")
412 throwErrnoIfMinus1Retry "flushReadBuffer"
413 (c_lseek (fromIntegral fd) (fromIntegral off) (#const SEEK_CUR))
414 return buf{ bufWPtr=0, bufRPtr=0 }
416 flushWriteBuffer :: FD -> Buffer -> IO Buffer
417 flushWriteBuffer fd buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = do
420 puts ("flushWriteBuffer, fd=" ++ show fd ++ ", bytes=" ++ show bytes ++ "\n")
423 then return (buf{ bufRPtr=0, bufWPtr=0 })
425 res <- throwErrnoIfMinus1RetryMayBlock "flushWriteBuffer"
426 (write_off (fromIntegral fd) b (fromIntegral r)
427 (fromIntegral bytes))
429 let res' = fromIntegral res
431 then flushWriteBuffer fd (buf{ bufRPtr = r + res' })
432 else return buf{ bufRPtr=0, bufWPtr=0 }
434 foreign import "write_wrap" unsafe
435 write_off :: CInt -> RawBuffer -> Int -> CInt -> IO CInt
437 int write_wrap(int fd, void *ptr, HsInt off, int size) \
438 { return write(fd, ptr + off, size); }
441 fillReadBuffer :: FD -> Bool -> Buffer -> IO Buffer
442 fillReadBuffer fd is_line
443 buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w, bufSize=size } =
444 -- buffer better be empty:
445 assert (r == 0 && w == 0) $ do
446 fillReadBufferLoop fd is_line buf b w size
448 -- For a line buffer, we just get the first chunk of data to arrive,
449 -- and don't wait for the whole buffer to be full (but we *do* wait
450 -- until some data arrives). This isn't really line buffering, but it
451 -- appears to be what GHC has done for a long time, and I suspect it
452 -- is more useful than line buffering in most cases.
454 fillReadBufferLoop fd is_line buf b w size = do
456 if bytes == 0 -- buffer full?
457 then return buf{ bufRPtr=0, bufWPtr=w }
460 puts ("fillReadBufferLoop: bytes = " ++ show bytes ++ "\n")
462 res <- throwErrnoIfMinus1RetryMayBlock "fillReadBuffer"
463 (read_off fd b (fromIntegral w) (fromIntegral bytes))
465 let res' = fromIntegral res
467 puts ("fillReadBufferLoop: res' = " ++ show res' ++ "\n")
472 else return buf{ bufRPtr=0, bufWPtr=w }
473 else if res' < bytes && not is_line
474 then fillReadBufferLoop fd is_line buf b (w+res') size
475 else return buf{ bufRPtr=0, bufWPtr=w+res' }
477 foreign import "read_wrap" unsafe
478 read_off :: FD -> RawBuffer -> Int -> CInt -> IO CInt
480 int read_wrap(int fd, void *ptr, HsInt off, int size) \
481 { return read(fd, ptr + off, size); }
483 -- ---------------------------------------------------------------------------
486 -- Three handles are allocated during program initialisation. The first
487 -- two manage input or output from the Haskell program's standard input
488 -- or output channel respectively. The third manages output to the
489 -- standard error channel. These handles are initially open.
496 stdin = unsafePerformIO $ do
497 -- ToDo: acquire lock
498 setNonBlockingFD fd_stdin
499 (buf, bmode) <- getBuffer fd_stdin ReadBuffer
500 spares <- newIORef BufferListNil
501 newFileHandle stdHandleFinalizer
502 (Handle__ { haFD = fd_stdin,
504 haIsBin = dEFAULT_OPEN_IN_BINARY_MODE,
505 haBufferMode = bmode,
506 haFilePath = "<stdin>",
512 stdout = unsafePerformIO $ do
513 -- ToDo: acquire lock
514 -- We don't set non-blocking mode on stdout or sterr, because
515 -- some shells don't recover properly.
516 -- setNonBlockingFD fd_stdout
517 (buf, bmode) <- getBuffer fd_stdout WriteBuffer
518 spares <- newIORef BufferListNil
519 newFileHandle stdHandleFinalizer
520 (Handle__ { haFD = fd_stdout,
521 haType = WriteHandle,
522 haIsBin = dEFAULT_OPEN_IN_BINARY_MODE,
523 haBufferMode = bmode,
524 haFilePath = "<stdout>",
530 stderr = unsafePerformIO $ do
531 -- ToDo: acquire lock
532 -- We don't set non-blocking mode on stdout or sterr, because
533 -- some shells don't recover properly.
534 -- setNonBlockingFD fd_stderr
536 spares <- newIORef BufferListNil
537 newFileHandle stdHandleFinalizer
538 (Handle__ { haFD = fd_stderr,
539 haType = WriteHandle,
540 haIsBin = dEFAULT_OPEN_IN_BINARY_MODE,
541 haBufferMode = NoBuffering,
542 haFilePath = "<stderr>",
547 -- ---------------------------------------------------------------------------
548 -- Opening and Closing Files
551 Computation `openFile file mode' allocates and returns a new, open
552 handle to manage the file `file'. It manages input if `mode'
553 is `ReadMode', output if `mode' is `WriteMode' or `AppendMode',
554 and both input and output if mode is `ReadWriteMode'.
556 If the file does not exist and it is opened for output, it should be
557 created as a new file. If `mode' is `WriteMode' and the file
558 already exists, then it should be truncated to zero length. The
559 handle is positioned at the end of the file if `mode' is
560 `AppendMode', and otherwise at the beginning (in which case its
561 internal position is 0).
563 Implementations should enforce, locally to the Haskell process,
564 multiple-reader single-writer locking on files, which is to say that
565 there may either be many handles on the same file which manage input,
566 or just one handle on the file which manages output. If any open or
567 semi-closed handle is managing a file for output, no new handle can be
568 allocated for that file. If any open or semi-closed handle is
569 managing a file for input, new handles can only be allocated if they
570 do not manage output.
572 Two files are the same if they have the same absolute name. An
573 implementation is free to impose stricter conditions.
576 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
577 deriving (Eq, Ord, Ix, Enum, Read, Show)
582 deriving (Eq, Read, Show)
584 addFilePathToIOError fun fp (IOException (IOError h iot _ str _))
585 = IOException (IOError h iot fun str (Just fp))
586 addFilePathToIOError _ _ other_exception
589 openFile :: FilePath -> IOMode -> IO Handle
592 (openFile' fp (if dEFAULT_OPEN_IN_BINARY_MODE
595 (\e -> throw (addFilePathToIOError "openFile" fp e))
597 openFileEx :: FilePath -> IOModeEx -> IO Handle
601 (\e -> throw (addFilePathToIOError "openFileEx" fp e))
604 openFile' filepath ex_mode =
605 withCString filepath $ \ f ->
610 BinaryMode bmo -> (bmo, True)
611 TextMode tmo -> (tmo, False)
613 oflags1 = case mode of
614 ReadMode -> read_flags
615 WriteMode -> write_flags
616 ReadWriteMode -> rw_flags
617 AppendMode -> append_flags
625 oflags = oflags1 .|. binary_flags
628 -- the old implementation had a complicated series of three opens,
629 -- which is perhaps because we have to be careful not to open
630 -- directories. However, the man pages I've read say that open()
631 -- always returns EISDIR if the file is a directory and was opened
632 -- for writing, so I think we're ok with a single open() here...
633 fd <- fromIntegral `liftM`
634 throwErrnoIfMinus1Retry "openFile"
635 (c_open f (fromIntegral oflags) 0o666)
637 openFd fd filepath mode binary
640 std_flags = o_NONBLOCK .|. o_NOCTTY
641 output_flags = std_flags .|. o_CREAT
642 read_flags = std_flags .|. o_RDONLY
643 write_flags = output_flags .|. o_WRONLY .|. o_TRUNC
644 rw_flags = output_flags .|. o_RDWR
645 append_flags = output_flags .|. o_WRONLY .|. o_APPEND
647 -- ---------------------------------------------------------------------------
650 openFd :: FD -> FilePath -> IOMode -> Bool -> IO Handle
651 openFd fd filepath mode binary = do
652 -- turn on non-blocking mode
655 let (ha_type, write) =
657 ReadMode -> ( ReadHandle, False )
658 WriteMode -> ( WriteHandle, True )
659 ReadWriteMode -> ( ReadWriteHandle, True )
660 AppendMode -> ( AppendHandle, True )
662 -- open() won't tell us if it was a directory if we only opened for
663 -- reading, so check again.
667 ioException (IOError Nothing InappropriateType "openFile"
668 "is a directory" Nothing)
671 | ReadWriteHandle <- ha_type -> mkDuplexHandle fd filepath binary
672 | otherwise -> mkFileHandle fd filepath ha_type binary
674 -- regular files need to be locked
676 r <- lockFile (fromIntegral fd) (fromBool write) 1{-exclusive-}
678 ioException (IOError Nothing ResourceBusy "openFile"
679 "file is locked" Nothing)
680 mkFileHandle fd filepath ha_type binary
683 foreign import "lockFile" unsafe
684 lockFile :: CInt -> CInt -> CInt -> IO CInt
686 foreign import "unlockFile" unsafe
687 unlockFile :: CInt -> IO CInt
689 mkFileHandle :: FD -> FilePath -> HandleType -> Bool -> IO Handle
690 mkFileHandle fd filepath ha_type binary = do
691 (buf, bmode) <- getBuffer fd (initBufferState ha_type)
692 spares <- newIORef BufferListNil
693 newFileHandle handleFinalizer
694 (Handle__ { haFD = fd,
697 haBufferMode = bmode,
698 haFilePath = filepath,
703 mkDuplexHandle :: FD -> FilePath -> Bool -> IO Handle
704 mkDuplexHandle fd filepath binary = do
705 (w_buf, w_bmode) <- getBuffer fd WriteBuffer
706 w_spares <- newIORef BufferListNil
708 Handle__ { haFD = fd,
709 haType = WriteHandle,
711 haBufferMode = w_bmode,
712 haFilePath = filepath,
716 write_side <- newMVar w_handle_
718 (r_buf, r_bmode) <- getBuffer fd ReadBuffer
719 r_spares <- newIORef BufferListNil
721 Handle__ { haFD = fd,
722 haType = ReadSideHandle write_side,
724 haBufferMode = r_bmode,
725 haFilePath = filepath,
729 read_side <- newMVar r_handle_
731 addMVarFinalizer write_side (handleFinalizer write_side)
732 return (DuplexHandle read_side write_side)
735 initBufferState ReadHandle = ReadBuffer
736 initBufferState _ = WriteBuffer
738 -- ---------------------------------------------------------------------------
741 -- Computation `hClose hdl' makes handle `hdl' closed. Before the
742 -- computation finishes, any items buffered for output and not already
743 -- sent to the operating system are flushed as for `hFlush'.
745 -- For a duplex handle, we close&flush the write side, and just close
748 hClose :: Handle -> IO ()
749 hClose h@(FileHandle m) = hClose' h m
750 hClose h@(DuplexHandle r w) = do
752 withHandle__' "hClose" h r $ \ handle_ -> do
753 return handle_{ haFD = -1,
754 haType = ClosedHandle
758 withHandle__' "hClose" h m $ \ handle_ -> do
759 case haType handle_ of
760 ClosedHandle -> return handle_
762 let fd = fromIntegral (haFD handle_)
763 flushWriteBufferOnly handle_
764 throwErrnoIfMinus1Retry_ "hClose" (c_close fd)
766 -- free the spare buffers
767 writeIORef (haBuffers handle_) BufferListNil
772 -- we must set the fd to -1, because the finalizer is going
773 -- to run eventually and try to close/unlock it.
774 return (handle_{ haFD = -1,
775 haType = ClosedHandle
778 -----------------------------------------------------------------------------
779 -- Detecting the size of a file
781 -- For a handle `hdl' which attached to a physical file, `hFileSize
782 -- hdl' returns the size of `hdl' in terms of the number of items
783 -- which can be read from `hdl'.
785 hFileSize :: Handle -> IO Integer
787 withHandle_ "hFileSize" handle $ \ handle_ -> do
788 case haType handle_ of
789 ClosedHandle -> ioe_closedHandle
790 SemiClosedHandle -> ioe_closedHandle
791 _ -> do flushWriteBufferOnly handle_
792 r <- fdFileSize (haFD handle_)
795 else ioException (IOError Nothing InappropriateType "hFileSize"
796 "not a regular file" Nothing)
798 -- ---------------------------------------------------------------------------
799 -- Detecting the End of Input
801 -- For a readable handle `hdl', `hIsEOF hdl' returns
802 -- `True' if no further input can be taken from `hdl' or for a
803 -- physical file, if the current I/O position is equal to the length of
804 -- the file. Otherwise, it returns `False'.
806 hIsEOF :: Handle -> IO Bool
809 (do hLookAhead handle; return False)
810 (\e -> if isEOFError e then return True else throw e)
815 -- ---------------------------------------------------------------------------
818 -- hLookahead returns the next character from the handle without
819 -- removing it from the input buffer, blocking until a character is
822 hLookAhead :: Handle -> IO Char
823 hLookAhead handle = do
824 wantReadableHandle "hLookAhead" handle $ \handle_ -> do
825 let ref = haBuffer handle_
827 is_line = haBufferMode handle_ == LineBuffering
830 -- fill up the read buffer if necessary
831 new_buf <- if bufferEmpty buf
832 then fillReadBuffer fd is_line buf
835 writeIORef ref new_buf
837 (c,_) <- readCharFromBuffer (bufBuf buf) (bufRPtr buf)
840 -- ---------------------------------------------------------------------------
841 -- Buffering Operations
843 -- Three kinds of buffering are supported: line-buffering,
844 -- block-buffering or no-buffering. See PrelIOBase for definition and
845 -- further explanation of what the type represent.
847 -- Computation `hSetBuffering hdl mode' sets the mode of buffering for
848 -- handle hdl on subsequent reads and writes.
850 -- * If mode is LineBuffering, line-buffering should be enabled if possible.
852 -- * If mode is `BlockBuffering size', then block-buffering
853 -- should be enabled if possible. The size of the buffer is n items
854 -- if size is `Just n' and is otherwise implementation-dependent.
856 -- * If mode is NoBuffering, then buffering is disabled if possible.
858 -- If the buffer mode is changed from BlockBuffering or
859 -- LineBuffering to NoBuffering, then any items in the output
860 -- buffer are written to the device, and any items in the input buffer
861 -- are discarded. The default buffering mode when a handle is opened
862 -- is implementation-dependent and may depend on the object which is
863 -- attached to that handle.
865 hSetBuffering :: Handle -> BufferMode -> IO ()
866 hSetBuffering handle mode =
867 withAllHandles__ "hSetBuffering" handle $ \ handle_ -> do
868 case haType handle_ of
869 ClosedHandle -> ioe_closedHandle
872 - we flush the old buffer regardless of whether
873 the new buffer could fit the contents of the old buffer
875 - allow a handle's buffering to change even if IO has
876 occurred (ANSI C spec. does not allow this, nor did
877 the previous implementation of IO.hSetBuffering).
878 - a non-standard extension is to allow the buffering
879 of semi-closed handles to change [sof 6/98]
883 let state = initBufferState (haType handle_)
886 -- we always have a 1-character read buffer for
887 -- unbuffered handles: it's needed to
888 -- support hLookAhead.
889 NoBuffering -> allocateBuffer 1 ReadBuffer
890 LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state
891 BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state
892 BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n
893 | otherwise -> allocateBuffer n state
894 writeIORef (haBuffer handle_) new_buf
896 -- for input terminals we need to put the terminal into
897 -- cooked or raw mode depending on the type of buffering.
898 is_tty <- fdIsTTY (haFD handle_)
899 when (is_tty && isReadableHandleType (haType handle_)) $
901 NoBuffering -> setCooked (haFD handle_) False
902 _ -> setCooked (haFD handle_) True
904 -- throw away spare buffers, they might be the wrong size
905 writeIORef (haBuffers handle_) BufferListNil
907 return (handle_{ haBufferMode = mode })
909 -- -----------------------------------------------------------------------------
912 -- The action `hFlush hdl' causes any items buffered for output
913 -- in handle `hdl' to be sent immediately to the operating
916 hFlush :: Handle -> IO ()
918 wantWritableHandle "hFlush" handle $ \ handle_ -> do
919 buf <- readIORef (haBuffer handle_)
920 if bufferIsWritable buf && not (bufferEmpty buf)
921 then do flushed_buf <- flushWriteBuffer (haFD handle_) buf
922 writeIORef (haBuffer handle_) flushed_buf
926 -- -----------------------------------------------------------------------------
927 -- Repositioning Handles
929 data HandlePosn = HandlePosn Handle HandlePosition
931 instance Eq HandlePosn where
932 (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2
934 -- HandlePosition is the Haskell equivalent of POSIX' off_t.
935 -- We represent it as an Integer on the Haskell side, but
936 -- cheat slightly in that hGetPosn calls upon a C helper
937 -- that reports the position back via (merely) an Int.
938 type HandlePosition = Integer
940 -- Computation `hGetPosn hdl' returns the current I/O position of
941 -- `hdl' as an abstract position. Computation `hSetPosn p' sets the
942 -- position of `hdl' to a previously obtained position `p'.
944 hGetPosn :: Handle -> IO HandlePosn
946 wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
949 -- urgh, on Windows we have to worry about \n -> \r\n translation,
950 -- so we can't easily calculate the file position using the
951 -- current buffer size. Just flush instead.
954 let fd = fromIntegral (haFD handle_)
955 posn <- fromIntegral `liftM`
956 throwErrnoIfMinus1Retry "hGetPosn"
957 (c_lseek fd 0 (#const SEEK_CUR))
959 let ref = haBuffer handle_
963 | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf)
964 | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf)
966 puts ("\nhGetPosn: (fd, posn, real_posn) = " ++ show (fd, posn, real_posn) ++ "\n")
967 puts (" (bufWPtr, bufRPtr) = " ++ show (bufWPtr buf, bufRPtr buf) ++ "\n")
969 return (HandlePosn handle real_posn)
972 hSetPosn :: HandlePosn -> IO ()
973 hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i
975 -- ---------------------------------------------------------------------------
979 The action `hSeek hdl mode i' sets the position of handle
980 `hdl' depending on `mode'. If `mode' is
982 * AbsoluteSeek - The position of `hdl' is set to `i'.
983 * RelativeSeek - The position of `hdl' is set to offset `i' from
984 the current position.
985 * SeekFromEnd - The position of `hdl' is set to offset `i' from
988 Some handles may not be seekable (see `hIsSeekable'), or only
989 support a subset of the possible positioning operations (e.g. it may
990 only be possible to seek to the end of a tape, or to a positive
991 offset from the beginning or current position).
993 It is not possible to set a negative I/O position, or for a physical
994 file, an I/O position beyond the current end-of-file.
997 - when seeking using `SeekFromEnd', positive offsets (>=0) means
998 seeking at or past EOF.
1000 - we possibly deviate from the report on the issue of seeking within
1001 the buffer and whether to flush it or not. The report isn't exactly
1005 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
1006 deriving (Eq, Ord, Ix, Enum, Read, Show)
1008 hSeek :: Handle -> SeekMode -> Integer -> IO ()
1009 hSeek handle mode offset =
1010 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
1012 puts ("hSeek " ++ show (mode,offset) ++ "\n")
1014 let ref = haBuffer handle_
1015 buf <- readIORef ref
1021 throwErrnoIfMinus1Retry_ "hSeek"
1022 (c_lseek (fromIntegral (haFD handle_)) (fromIntegral offset) whence)
1025 whence = case mode of
1026 AbsoluteSeek -> (#const SEEK_SET)
1027 RelativeSeek -> (#const SEEK_CUR)
1028 SeekFromEnd -> (#const SEEK_END)
1030 if bufferIsWritable buf
1031 then do new_buf <- flushWriteBuffer fd buf
1032 writeIORef ref new_buf
1036 if mode == RelativeSeek && offset >= 0 && offset < fromIntegral (w - r)
1037 then writeIORef ref buf{ bufRPtr = r + fromIntegral offset }
1040 new_buf <- flushReadBuffer (haFD handle_) buf
1041 writeIORef ref new_buf
1044 -- -----------------------------------------------------------------------------
1045 -- Handle Properties
1047 -- A number of operations return information about the properties of a
1048 -- handle. Each of these operations returns `True' if the handle has
1049 -- the specified property, and `False' otherwise.
1051 hIsOpen :: Handle -> IO Bool
1053 withHandle_ "hIsOpen" handle $ \ handle_ -> do
1054 case haType handle_ of
1055 ClosedHandle -> return False
1056 SemiClosedHandle -> return False
1059 hIsClosed :: Handle -> IO Bool
1061 withHandle_ "hIsClosed" handle $ \ handle_ -> do
1062 case haType handle_ of
1063 ClosedHandle -> return True
1066 {- not defined, nor exported, but mentioned
1067 here for documentation purposes:
1069 hSemiClosed :: Handle -> IO Bool
1073 return (not (ho || hc))
1076 hIsReadable :: Handle -> IO Bool
1077 hIsReadable (DuplexHandle _ _) = return True
1078 hIsReadable handle =
1079 withHandle_ "hIsReadable" handle $ \ handle_ -> do
1080 case haType handle_ of
1081 ClosedHandle -> ioe_closedHandle
1082 SemiClosedHandle -> ioe_closedHandle
1083 htype -> return (isReadableHandleType htype)
1085 hIsWritable :: Handle -> IO Bool
1086 hIsWritable (DuplexHandle _ _) = return False
1087 hIsWritable handle =
1088 withHandle_ "hIsWritable" handle $ \ handle_ -> do
1089 case haType handle_ of
1090 ClosedHandle -> ioe_closedHandle
1091 SemiClosedHandle -> ioe_closedHandle
1092 htype -> return (isWritableHandleType htype)
1094 -- Querying how a handle buffers its data:
1096 hGetBuffering :: Handle -> IO BufferMode
1097 hGetBuffering handle =
1098 withHandle_ "hGetBuffering" handle $ \ handle_ -> do
1099 case haType handle_ of
1100 ClosedHandle -> ioe_closedHandle
1102 -- We're being non-standard here, and allow the buffering
1103 -- of a semi-closed handle to be queried. -- sof 6/98
1104 return (haBufferMode handle_) -- could be stricter..
1106 hIsSeekable :: Handle -> IO Bool
1107 hIsSeekable handle =
1108 withHandle_ "hIsSeekable" handle $ \ handle_ -> do
1109 case haType handle_ of
1110 ClosedHandle -> ioe_closedHandle
1111 SemiClosedHandle -> ioe_closedHandle
1112 AppendHandle -> return False
1113 _ -> do t <- fdType (haFD handle_)
1114 return (t == RegularFile && haIsBin handle_)
1116 -- -----------------------------------------------------------------------------
1117 -- Changing echo status
1119 -- Non-standard GHC extension is to allow the echoing status
1120 -- of a handles connected to terminals to be reconfigured:
1122 hSetEcho :: Handle -> Bool -> IO ()
1123 hSetEcho handle on = do
1124 isT <- hIsTerminalDevice handle
1128 withHandle_ "hSetEcho" handle $ \ handle_ -> do
1129 case haType handle_ of
1130 ClosedHandle -> ioe_closedHandle
1131 _ -> setEcho (haFD handle_) on
1133 hGetEcho :: Handle -> IO Bool
1134 hGetEcho handle = do
1135 isT <- hIsTerminalDevice handle
1139 withHandle_ "hGetEcho" handle $ \ handle_ -> do
1140 case haType handle_ of
1141 ClosedHandle -> ioe_closedHandle
1142 _ -> getEcho (haFD handle_)
1144 hIsTerminalDevice :: Handle -> IO Bool
1145 hIsTerminalDevice handle = do
1146 withHandle_ "hIsTerminalDevice" handle $ \ handle_ -> do
1147 case haType handle_ of
1148 ClosedHandle -> ioe_closedHandle
1149 _ -> fdIsTTY (haFD handle_)
1151 -- -----------------------------------------------------------------------------
1155 hSetBinaryMode handle bin =
1156 withHandle "hSetBinaryMode" handle $ \ handle_ ->
1157 do let flg | bin = (#const O_BINARY)
1158 | otherwise = (#const O_TEXT)
1159 throwErrnoIfMinus1_ "hSetBinaryMode"
1160 (setmode (fromIntegral (haFD handle_)) flg)
1161 return (handle_{haIsBin=bin}, ())
1163 foreign import "setmode" setmode :: CInt -> CInt -> IO CInt
1165 hSetBinaryMode handle bin =
1166 withHandle "hSetBinaryMode" handle $ \ handle_ ->
1167 return (handle_{haIsBin=bin}, ())
1170 -- -----------------------------------------------------------------------------
1173 -- These three functions are meant to get things out of an IOError.
1175 ioeGetFileName :: IOError -> Maybe FilePath
1176 ioeGetErrorString :: IOError -> String
1177 ioeGetHandle :: IOError -> Maybe Handle
1179 ioeGetHandle (IOException (IOError h _ _ _ _)) = h
1180 ioeGetHandle (UserError _) = Nothing
1181 ioeGetHandle _ = error "IO.ioeGetHandle: not an IO error"
1183 ioeGetErrorString (IOException (IOError _ iot _ _ _)) = show iot
1184 ioeGetErrorString (UserError str) = str
1185 ioeGetErrorString _ = error "IO.ioeGetErrorString: not an IO error"
1187 ioeGetFileName (IOException (IOError _ _ _ _ fn)) = fn
1188 ioeGetFileName (UserError _) = Nothing
1189 ioeGetFileName _ = error "IO.ioeGetFileName: not an IO error"
1191 -- ---------------------------------------------------------------------------
1195 puts :: String -> IO ()
1196 puts s = withCString s $ \cstr -> do c_write 1 cstr (fromIntegral (length s))