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 readRawBuffer, readRawBufferPtr,
27 writeRawBuffer, writeRawBufferPtr,
30 {- ought to be unnecessary, but just in case.. -}
31 write_off, write_rawBuffer,
32 read_off, read_rawBuffer,
34 ioe_closedHandle, ioe_EOF, ioe_notReadable, ioe_notWritable,
36 stdin, stdout, stderr,
37 IOMode(..), openFile, openBinaryFile, openFd, fdToHandle,
38 hFileSize, hIsEOF, isEOF, hLookAhead, hSetBuffering, hSetBinaryMode,
39 hFlush, hDuplicate, hDuplicateTo,
43 HandlePosn(..), hGetPosn, hSetPosn,
44 SeekMode(..), hSeek, hTell,
46 hIsOpen, hIsClosed, hIsReadable, hIsWritable, hGetBuffering, hIsSeekable,
47 hSetEcho, hGetEcho, hIsTerminalDevice,
64 import System.IO.Error
65 import System.Posix.Internals
71 import GHC.Read ( Read )
76 import GHC.Num ( Integer(..), Num(..) )
78 import GHC.Real ( toInteger )
82 -- -----------------------------------------------------------------------------
85 -- hWaitForInput blocks (should use a timeout)
87 -- unbuffered hGetLine is a bit dodgy
89 -- hSetBuffering: can't change buffering on a stream,
90 -- when the read buffer is non-empty? (no way to flush the buffer)
92 -- ---------------------------------------------------------------------------
93 -- Are files opened by default in text or binary mode, if the user doesn't
96 dEFAULT_OPEN_IN_BINARY_MODE = False :: Bool
98 -- ---------------------------------------------------------------------------
99 -- Creating a new handle
101 newFileHandle :: FilePath -> (MVar Handle__ -> IO ()) -> Handle__ -> IO Handle
102 newFileHandle filepath finalizer hc = do
104 addMVarFinalizer m (finalizer m)
105 return (FileHandle filepath m)
107 -- ---------------------------------------------------------------------------
108 -- Working with Handles
111 In the concurrent world, handles are locked during use. This is done
112 by wrapping an MVar around the handle which acts as a mutex over
113 operations on the handle.
115 To avoid races, we use the following bracketing operations. The idea
116 is to obtain the lock, do some operation and replace the lock again,
117 whether the operation succeeded or failed. We also want to handle the
118 case where the thread receives an exception while processing the IO
119 operation: in these cases we also want to relinquish the lock.
121 There are three versions of @withHandle@: corresponding to the three
122 possible combinations of:
124 - the operation may side-effect the handle
125 - the operation may return a result
127 If the operation generates an error or an exception is raised, the
128 original handle is always replaced [ this is the case at the moment,
129 but we might want to revisit this in the future --SDM ].
132 {-# INLINE withHandle #-}
133 withHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
134 withHandle fun h@(FileHandle _ m) act = withHandle' fun h m act
135 withHandle fun h@(DuplexHandle _ m _) act = withHandle' fun h m act
137 withHandle' :: String -> Handle -> MVar Handle__
138 -> (Handle__ -> IO (Handle__,a)) -> IO a
139 withHandle' fun h m act =
142 checkBufferInvariants h_
143 (h',v) <- catchException (act h_)
144 (\ err -> putMVar m h_ >>
146 IOException ex -> ioError (augmentIOError ex fun h)
148 checkBufferInvariants h'
152 {-# INLINE withHandle_ #-}
153 withHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
154 withHandle_ fun h@(FileHandle _ m) act = withHandle_' fun h m act
155 withHandle_ fun h@(DuplexHandle _ m _) act = withHandle_' fun h m act
157 withHandle_' fun h m act =
160 checkBufferInvariants h_
161 v <- catchException (act h_)
162 (\ err -> putMVar m h_ >>
164 IOException ex -> ioError (augmentIOError ex fun h)
166 checkBufferInvariants h_
170 withAllHandles__ :: String -> Handle -> (Handle__ -> IO Handle__) -> IO ()
171 withAllHandles__ fun h@(FileHandle _ m) act = withHandle__' fun h m act
172 withAllHandles__ fun h@(DuplexHandle _ r w) act = do
173 withHandle__' fun h r act
174 withHandle__' fun h w act
176 withHandle__' fun h m act =
179 checkBufferInvariants h_
180 h' <- catchException (act h_)
181 (\ err -> putMVar m h_ >>
183 IOException ex -> ioError (augmentIOError ex fun h)
185 checkBufferInvariants h'
189 augmentIOError (IOError _ iot _ str fp) fun h
190 = IOError (Just h) iot fun str filepath
193 | otherwise = case h of
194 FileHandle fp _ -> Just fp
195 DuplexHandle fp _ _ -> Just fp
197 -- ---------------------------------------------------------------------------
198 -- Wrapper for write operations.
200 wantWritableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
201 wantWritableHandle fun h@(FileHandle _ m) act
202 = wantWritableHandle' fun h m act
203 wantWritableHandle fun h@(DuplexHandle _ _ m) act
204 = wantWritableHandle' fun h m act
205 -- ToDo: in the Duplex case, we don't need to checkWritableHandle
208 :: String -> Handle -> MVar Handle__
209 -> (Handle__ -> IO a) -> IO a
210 wantWritableHandle' fun h m act
211 = withHandle_' fun h m (checkWritableHandle act)
213 checkWritableHandle act handle_
214 = case haType handle_ of
215 ClosedHandle -> ioe_closedHandle
216 SemiClosedHandle -> ioe_closedHandle
217 ReadHandle -> ioe_notWritable
218 ReadWriteHandle -> do
219 let ref = haBuffer handle_
222 if not (bufferIsWritable buf)
223 then do b <- flushReadBuffer (haFD handle_) buf
224 return b{ bufState=WriteBuffer }
226 writeIORef ref new_buf
228 _other -> act handle_
230 -- ---------------------------------------------------------------------------
231 -- Wrapper for read operations.
233 wantReadableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
234 wantReadableHandle fun h@(FileHandle _ m) act
235 = wantReadableHandle' fun h m act
236 wantReadableHandle fun h@(DuplexHandle _ m _) act
237 = wantReadableHandle' fun h m act
238 -- ToDo: in the Duplex case, we don't need to checkReadableHandle
241 :: String -> Handle -> MVar Handle__
242 -> (Handle__ -> IO a) -> IO a
243 wantReadableHandle' fun h m act
244 = withHandle_' fun h m (checkReadableHandle act)
246 checkReadableHandle act handle_ =
247 case haType handle_ of
248 ClosedHandle -> ioe_closedHandle
249 SemiClosedHandle -> ioe_closedHandle
250 AppendHandle -> ioe_notReadable
251 WriteHandle -> ioe_notReadable
252 ReadWriteHandle -> do
253 let ref = haBuffer handle_
255 when (bufferIsWritable buf) $ do
256 new_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf
257 writeIORef ref new_buf{ bufState=ReadBuffer }
259 _other -> act handle_
261 -- ---------------------------------------------------------------------------
262 -- Wrapper for seek operations.
264 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
265 wantSeekableHandle fun h@(DuplexHandle _ _ _) _act =
266 ioException (IOError (Just h) IllegalOperation fun
267 "handle is not seekable" Nothing)
268 wantSeekableHandle fun h@(FileHandle _ m) act =
269 withHandle_' fun h m (checkSeekableHandle act)
271 checkSeekableHandle act handle_ =
272 case haType handle_ of
273 ClosedHandle -> ioe_closedHandle
274 SemiClosedHandle -> ioe_closedHandle
275 AppendHandle -> ioe_notSeekable
276 _ | haIsBin handle_ || tEXT_MODE_SEEK_ALLOWED -> act handle_
277 | otherwise -> ioe_notSeekable_notBin
279 -- -----------------------------------------------------------------------------
282 ioe_closedHandle, ioe_EOF,
283 ioe_notReadable, ioe_notWritable,
284 ioe_notSeekable, ioe_notSeekable_notBin :: IO a
286 ioe_closedHandle = ioException
287 (IOError Nothing IllegalOperation ""
288 "handle is closed" Nothing)
289 ioe_EOF = ioException
290 (IOError Nothing EOF "" "" Nothing)
291 ioe_notReadable = ioException
292 (IOError Nothing IllegalOperation ""
293 "handle is not open for reading" Nothing)
294 ioe_notWritable = ioException
295 (IOError Nothing IllegalOperation ""
296 "handle is not open for writing" Nothing)
297 ioe_notSeekable = ioException
298 (IOError Nothing IllegalOperation ""
299 "handle is not seekable" Nothing)
300 ioe_notSeekable_notBin = ioException
301 (IOError Nothing IllegalOperation ""
302 "seek operations on text-mode handles are not allowed on this platform"
305 ioe_bufsiz :: Int -> IO a
306 ioe_bufsiz n = ioException
307 (IOError Nothing InvalidArgument "hSetBuffering"
308 ("illegal buffer size " ++ showsPrec 9 n []) Nothing)
309 -- 9 => should be parens'ified.
311 -- -----------------------------------------------------------------------------
314 -- For a duplex handle, we arrange that the read side points to the write side
315 -- (and hence keeps it alive if the read side is alive). This is done by
316 -- having the haOtherSide field of the read side point to the read side.
317 -- The finalizer is then placed on the write side, and the handle only gets
318 -- finalized once, when both sides are no longer required.
320 stdHandleFinalizer :: MVar Handle__ -> IO ()
321 stdHandleFinalizer m = do
323 flushWriteBufferOnly h_
325 handleFinalizer :: MVar Handle__ -> IO ()
326 handleFinalizer m = do
327 handle_ <- takeMVar m
328 case haType handle_ of
329 ClosedHandle -> return ()
330 _ -> do flushWriteBufferOnly handle_ `catchException` \_ -> return ()
331 -- ignore errors and async exceptions, and close the
332 -- descriptor anyway...
333 hClose_handle_ handle_
336 -- ---------------------------------------------------------------------------
337 -- Grimy buffer operations
340 checkBufferInvariants h_ = do
341 let ref = haBuffer h_
342 Buffer{ bufWPtr=w, bufRPtr=r, bufSize=size, bufState=state } <- readIORef ref
347 && ( r /= w || (r == 0 && w == 0) )
348 && ( state /= WriteBuffer || r == 0 )
349 && ( state /= WriteBuffer || w < size ) -- write buffer is never full
351 then error "buffer invariant violation"
354 checkBufferInvariants h_ = return ()
357 newEmptyBuffer :: RawBuffer -> BufferState -> Int -> Buffer
358 newEmptyBuffer b state size
359 = Buffer{ bufBuf=b, bufRPtr=0, bufWPtr=0, bufSize=size, bufState=state }
361 allocateBuffer :: Int -> BufferState -> IO Buffer
362 allocateBuffer sz@(I# size) state = IO $ \s ->
363 #ifdef mingw32_TARGET_OS
364 -- To implement asynchronous I/O under Win32, we have to pass
365 -- buffer references to external threads that handles the
366 -- filling/emptying of their contents. Hence, the buffer cannot
367 -- be moved around by the GC.
368 case newPinnedByteArray# size s of { (# s, b #) ->
370 case newByteArray# size s of { (# s, b #) ->
372 (# s, newEmptyBuffer b state sz #) }
374 writeCharIntoBuffer :: RawBuffer -> Int -> Char -> IO Int
375 writeCharIntoBuffer slab (I# off) (C# c)
376 = IO $ \s -> case writeCharArray# slab off c s of
377 s -> (# s, I# (off +# 1#) #)
379 readCharFromBuffer :: RawBuffer -> Int -> IO (Char, Int)
380 readCharFromBuffer slab (I# off)
381 = IO $ \s -> case readCharArray# slab off s of
382 (# s, c #) -> (# s, (C# c, I# (off +# 1#)) #)
384 getBuffer :: FD -> BufferState -> IO (IORef Buffer, BufferMode)
385 getBuffer fd state = do
386 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE state
387 ioref <- newIORef buffer
391 | is_tty = LineBuffering
392 | otherwise = BlockBuffering Nothing
394 return (ioref, buffer_mode)
396 mkUnBuffer :: IO (IORef Buffer)
398 buffer <- allocateBuffer 1 ReadBuffer
401 -- flushWriteBufferOnly flushes the buffer iff it contains pending write data.
402 flushWriteBufferOnly :: Handle__ -> IO ()
403 flushWriteBufferOnly h_ = do
407 new_buf <- if bufferIsWritable buf
408 then flushWriteBuffer fd (haIsStream h_) buf
410 writeIORef ref new_buf
412 -- flushBuffer syncs the file with the buffer, including moving the
413 -- file pointer backwards in the case of a read buffer.
414 flushBuffer :: Handle__ -> IO ()
416 let ref = haBuffer h_
421 ReadBuffer -> flushReadBuffer (haFD h_) buf
422 WriteBuffer -> flushWriteBuffer (haFD h_) (haIsStream h_) buf
424 writeIORef ref flushed_buf
426 -- When flushing a read buffer, we seek backwards by the number of
427 -- characters in the buffer. The file descriptor must therefore be
428 -- seekable: attempting to flush the read buffer on an unseekable
429 -- handle is not allowed.
431 flushReadBuffer :: FD -> Buffer -> IO Buffer
432 flushReadBuffer fd buf
433 | bufferEmpty buf = return buf
435 let off = negate (bufWPtr buf - bufRPtr buf)
437 puts ("flushReadBuffer: new file offset = " ++ show off ++ "\n")
439 throwErrnoIfMinus1Retry "flushReadBuffer"
440 (c_lseek (fromIntegral fd) (fromIntegral off) sEEK_CUR)
441 return buf{ bufWPtr=0, bufRPtr=0 }
443 flushWriteBuffer :: FD -> Bool -> Buffer -> IO Buffer
444 flushWriteBuffer fd is_stream buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = do
447 puts ("flushWriteBuffer, fd=" ++ show fd ++ ", bytes=" ++ show bytes ++ "\n")
450 then return (buf{ bufRPtr=0, bufWPtr=0 })
452 res <- writeRawBuffer "flushWriteBuffer" (fromIntegral fd) is_stream b
453 (fromIntegral r) (fromIntegral bytes)
454 let res' = fromIntegral res
456 then flushWriteBuffer fd is_stream (buf{ bufRPtr = r + res' })
457 else return buf{ bufRPtr=0, bufWPtr=0 }
459 fillReadBuffer :: FD -> Bool -> Bool -> Buffer -> IO Buffer
460 fillReadBuffer fd is_line is_stream
461 buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w, bufSize=size } =
462 -- buffer better be empty:
463 assert (r == 0 && w == 0) $ do
464 fillReadBufferLoop fd is_line is_stream buf b w size
466 -- For a line buffer, we just get the first chunk of data to arrive,
467 -- and don't wait for the whole buffer to be full (but we *do* wait
468 -- until some data arrives). This isn't really line buffering, but it
469 -- appears to be what GHC has done for a long time, and I suspect it
470 -- is more useful than line buffering in most cases.
472 fillReadBufferLoop fd is_line is_stream buf b w size = do
474 if bytes == 0 -- buffer full?
475 then return buf{ bufRPtr=0, bufWPtr=w }
478 puts ("fillReadBufferLoop: bytes = " ++ show bytes ++ "\n")
480 res <- readRawBuffer "fillReadBuffer" fd is_stream b
481 (fromIntegral w) (fromIntegral bytes)
482 let res' = fromIntegral res
484 puts ("fillReadBufferLoop: res' = " ++ show res' ++ "\n")
489 else return buf{ bufRPtr=0, bufWPtr=w }
490 else if res' < bytes && not is_line
491 then fillReadBufferLoop fd is_line is_stream buf b (w+res') size
492 else return buf{ bufRPtr=0, bufWPtr=w+res' }
495 -- Low level routines for reading/writing to (raw)buffers:
497 #ifndef mingw32_TARGET_OS
498 readRawBuffer :: String -> FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
499 readRawBuffer loc fd is_stream buf off len =
500 throwErrnoIfMinus1RetryMayBlock loc
501 (read_rawBuffer fd is_stream buf off len)
504 readRawBufferPtr :: String -> FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
505 readRawBufferPtr loc fd is_stream buf off len =
506 throwErrnoIfMinus1RetryMayBlock loc
507 (read_off fd is_stream buf off len)
510 writeRawBuffer :: String -> FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
511 writeRawBuffer loc fd is_stream buf off len =
512 throwErrnoIfMinus1RetryMayBlock loc
513 (write_rawBuffer (fromIntegral fd) is_stream buf off len)
516 writeRawBufferPtr :: String -> FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
517 writeRawBufferPtr loc fd is_stream buf off len =
518 throwErrnoIfMinus1RetryMayBlock loc
519 (write_off (fromIntegral fd) is_stream buf off len)
522 foreign import ccall unsafe "__hscore_PrelHandle_read"
523 read_rawBuffer :: FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
525 foreign import ccall unsafe "__hscore_PrelHandle_read"
526 read_off :: FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
528 foreign import ccall unsafe "__hscore_PrelHandle_write"
529 write_rawBuffer :: CInt -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
531 foreign import ccall unsafe "__hscore_PrelHandle_write"
532 write_off :: CInt -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
535 readRawBuffer :: String -> FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
536 readRawBuffer loc fd is_stream buf off len = do
537 (l, rc) <- asyncReadBA fd (if is_stream then 1 else 0) (fromIntegral len) off buf
540 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
541 else return (fromIntegral l)
543 readRawBufferPtr :: String -> FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
544 readRawBufferPtr loc fd is_stream buf off len = do
545 (l, rc) <- asyncRead fd (if is_stream then 1 else 0) (fromIntegral len) (buf `plusPtr` off)
548 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
549 else return (fromIntegral l)
551 writeRawBuffer :: String -> FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
552 writeRawBuffer loc fd is_stream buf off len = do
553 (l, rc) <- asyncWriteBA fd (if is_stream then 1 else 0) (fromIntegral len) off buf
556 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
557 else return (fromIntegral l)
559 writeRawBufferPtr :: String -> FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
560 writeRawBufferPtr loc fd is_stream buf off len = do
561 (l, rc) <- asyncWrite fd (if is_stream then 1 else 0) (fromIntegral len) (buf `plusPtr` off)
564 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
565 else return (fromIntegral l)
567 foreign import ccall unsafe "__hscore_PrelHandle_read"
568 read_rawBuffer :: FD -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
570 foreign import ccall unsafe "__hscore_PrelHandle_read"
571 read_off :: FD -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
573 foreign import ccall unsafe "__hscore_PrelHandle_write"
574 write_rawBuffer :: CInt -> Bool -> RawBuffer -> Int -> CInt -> IO CInt
576 foreign import ccall unsafe "__hscore_PrelHandle_write"
577 write_off :: CInt -> Bool -> Ptr CChar -> Int -> CInt -> IO CInt
581 -- ---------------------------------------------------------------------------
584 -- Three handles are allocated during program initialisation. The first
585 -- two manage input or output from the Haskell program's standard input
586 -- or output channel respectively. The third manages output to the
587 -- standard error channel. These handles are initially open.
594 stdin = unsafePerformIO $ do
595 -- ToDo: acquire lock
596 setNonBlockingFD fd_stdin
597 (buf, bmode) <- getBuffer fd_stdin ReadBuffer
598 mkStdHandle fd_stdin "<stdin>" ReadHandle buf bmode
601 stdout = unsafePerformIO $ do
602 -- ToDo: acquire lock
603 -- We don't set non-blocking mode on stdout or sterr, because
604 -- some shells don't recover properly.
605 -- setNonBlockingFD fd_stdout
606 (buf, bmode) <- getBuffer fd_stdout WriteBuffer
607 mkStdHandle fd_stdout "<stdout>" WriteHandle buf bmode
610 stderr = unsafePerformIO $ do
611 -- ToDo: acquire lock
612 -- We don't set non-blocking mode on stdout or sterr, because
613 -- some shells don't recover properly.
614 -- setNonBlockingFD fd_stderr
616 mkStdHandle fd_stderr "<stderr>" WriteHandle buf NoBuffering
618 -- ---------------------------------------------------------------------------
619 -- Opening and Closing Files
622 Computation `openFile file mode' allocates and returns a new, open
623 handle to manage the file `file'. It manages input if `mode'
624 is `ReadMode', output if `mode' is `WriteMode' or `AppendMode',
625 and both input and output if mode is `ReadWriteMode'.
627 If the file does not exist and it is opened for output, it should be
628 created as a new file. If `mode' is `WriteMode' and the file
629 already exists, then it should be truncated to zero length. The
630 handle is positioned at the end of the file if `mode' is
631 `AppendMode', and otherwise at the beginning (in which case its
632 internal position is 0).
634 Implementations should enforce, locally to the Haskell process,
635 multiple-reader single-writer locking on files, which is to say that
636 there may either be many handles on the same file which manage input,
637 or just one handle on the file which manages output. If any open or
638 semi-closed handle is managing a file for output, no new handle can be
639 allocated for that file. If any open or semi-closed handle is
640 managing a file for input, new handles can only be allocated if they
641 do not manage output.
643 Two files are the same if they have the same absolute name. An
644 implementation is free to impose stricter conditions.
647 addFilePathToIOError fun fp (IOError h iot _ str _)
648 = IOError h iot fun str (Just fp)
650 openFile :: FilePath -> IOMode -> IO Handle
653 (openFile' fp im dEFAULT_OPEN_IN_BINARY_MODE)
654 (\e -> ioError (addFilePathToIOError "openFile" fp e))
656 openBinaryFile :: FilePath -> IOMode -> IO Handle
657 openBinaryFile fp m =
659 (openFile' fp m True)
660 (\e -> ioError (addFilePathToIOError "openBinaryFile" fp e))
662 openFile' filepath mode binary =
663 withCString filepath $ \ f ->
666 oflags1 = case mode of
667 ReadMode -> read_flags
668 WriteMode -> write_flags
669 ReadWriteMode -> rw_flags
670 AppendMode -> append_flags
672 truncate | WriteMode <- mode = True
679 oflags = oflags1 .|. binary_flags
682 -- the old implementation had a complicated series of three opens,
683 -- which is perhaps because we have to be careful not to open
684 -- directories. However, the man pages I've read say that open()
685 -- always returns EISDIR if the file is a directory and was opened
686 -- for writing, so I think we're ok with a single open() here...
687 fd <- fromIntegral `liftM`
688 throwErrnoIfMinus1Retry "openFile"
689 (c_open f (fromIntegral oflags) 0o666)
691 openFd fd Nothing filepath mode binary truncate
692 -- ASSERT: if we just created the file, then openFd won't fail
693 -- (so we don't need to worry about removing the newly created file
694 -- in the event of an error).
697 std_flags = o_NONBLOCK .|. o_NOCTTY
698 output_flags = std_flags .|. o_CREAT
699 read_flags = std_flags .|. o_RDONLY
700 write_flags = output_flags .|. o_WRONLY
701 rw_flags = output_flags .|. o_RDWR
702 append_flags = write_flags .|. o_APPEND
704 -- ---------------------------------------------------------------------------
707 openFd :: FD -> Maybe FDType -> FilePath -> IOMode -> Bool -> Bool -> IO Handle
708 openFd fd mb_fd_type filepath mode binary truncate = do
709 -- turn on non-blocking mode
712 let (ha_type, write) =
714 ReadMode -> ( ReadHandle, False )
715 WriteMode -> ( WriteHandle, True )
716 ReadWriteMode -> ( ReadWriteHandle, True )
717 AppendMode -> ( AppendHandle, True )
719 -- open() won't tell us if it was a directory if we only opened for
720 -- reading, so check again.
725 let is_stream = fd_type == Stream
728 ioException (IOError Nothing InappropriateType "openFile"
729 "is a directory" Nothing)
732 | ReadWriteHandle <- ha_type -> mkDuplexHandle fd is_stream filepath binary
733 | otherwise -> mkFileHandle fd is_stream filepath ha_type binary
735 -- regular files need to be locked
737 r <- lockFile (fromIntegral fd) (fromBool write) 1{-exclusive-}
739 ioException (IOError Nothing ResourceBusy "openFile"
740 "file is locked" Nothing)
742 -- truncate the file if necessary
743 when truncate (fileTruncate filepath)
745 mkFileHandle fd is_stream filepath ha_type binary
748 fdToHandle :: FD -> IO Handle
751 let fd_str = "<file descriptor: " ++ show fd ++ ">"
752 openFd fd Nothing fd_str mode True{-bin mode-} False{-no truncate-}
754 foreign import ccall unsafe "lockFile"
755 lockFile :: CInt -> CInt -> CInt -> IO CInt
757 foreign import ccall unsafe "unlockFile"
758 unlockFile :: CInt -> IO CInt
760 mkStdHandle :: FD -> FilePath -> HandleType -> IORef Buffer -> BufferMode
762 mkStdHandle fd filepath ha_type buf bmode = do
763 spares <- newIORef BufferListNil
764 newFileHandle filepath stdHandleFinalizer
765 (Handle__ { haFD = fd,
767 haIsBin = dEFAULT_OPEN_IN_BINARY_MODE,
769 haBufferMode = bmode,
772 haOtherSide = Nothing
775 mkFileHandle :: FD -> Bool -> FilePath -> HandleType -> Bool -> IO Handle
776 mkFileHandle fd is_stream filepath ha_type binary = do
777 (buf, bmode) <- getBuffer fd (initBufferState ha_type)
778 spares <- newIORef BufferListNil
779 newFileHandle filepath handleFinalizer
780 (Handle__ { haFD = fd,
783 haIsStream = is_stream,
784 haBufferMode = bmode,
787 haOtherSide = Nothing
790 mkDuplexHandle :: FD -> Bool -> FilePath -> Bool -> IO Handle
791 mkDuplexHandle fd is_stream filepath binary = do
792 (w_buf, w_bmode) <- getBuffer fd WriteBuffer
793 w_spares <- newIORef BufferListNil
795 Handle__ { haFD = fd,
796 haType = WriteHandle,
798 haIsStream = is_stream,
799 haBufferMode = w_bmode,
801 haBuffers = w_spares,
802 haOtherSide = Nothing
804 write_side <- newMVar w_handle_
806 (r_buf, r_bmode) <- getBuffer fd ReadBuffer
807 r_spares <- newIORef BufferListNil
809 Handle__ { haFD = fd,
812 haIsStream = is_stream,
813 haBufferMode = r_bmode,
815 haBuffers = r_spares,
816 haOtherSide = Just write_side
818 read_side <- newMVar r_handle_
820 addMVarFinalizer write_side (handleFinalizer write_side)
821 return (DuplexHandle filepath read_side write_side)
824 initBufferState ReadHandle = ReadBuffer
825 initBufferState _ = WriteBuffer
827 -- ---------------------------------------------------------------------------
830 -- Computation `hClose hdl' makes handle `hdl' closed. Before the
831 -- computation finishes, any items buffered for output and not already
832 -- sent to the operating system are flushed as for `hFlush'.
834 -- For a duplex handle, we close&flush the write side, and just close
837 hClose :: Handle -> IO ()
838 hClose h@(FileHandle _ m) = hClose' h m
839 hClose h@(DuplexHandle _ r w) = hClose' h w >> hClose' h r
841 hClose' h m = withHandle__' "hClose" h m $ hClose_help
843 -- hClose_help is also called by lazyRead (in PrelIO) when EOF is read
844 -- or an IO error occurs on a lazy stream. The semi-closed Handle is
845 -- then closed immediately. We have to be careful with DuplexHandles
846 -- though: we have to leave the closing to the finalizer in that case,
847 -- because the write side may still be in use.
848 hClose_help :: Handle__ -> IO Handle__
849 hClose_help handle_ =
850 case haType handle_ of
851 ClosedHandle -> return handle_
852 _ -> do flushWriteBufferOnly handle_ -- interruptible
853 hClose_handle_ handle_
855 hClose_handle_ handle_ = do
856 let fd = haFD handle_
857 c_fd = fromIntegral fd
859 -- close the file descriptor, but not when this is the read
860 -- side of a duplex handle, and not when this is one of the
862 case haOtherSide handle_ of
864 when (fd /= fd_stdin && fd /= fd_stdout && fd /= fd_stderr) $
865 throwErrnoIfMinus1Retry_ "hClose"
866 #ifdef mingw32_TARGET_OS
867 (closeFd (haIsStream handle_) c_fd)
873 -- free the spare buffers
874 writeIORef (haBuffers handle_) BufferListNil
879 -- we must set the fd to -1, because the finalizer is going
880 -- to run eventually and try to close/unlock it.
881 return (handle_{ haFD = -1,
882 haType = ClosedHandle
885 -----------------------------------------------------------------------------
886 -- Detecting the size of a file
888 -- For a handle `hdl' which attached to a physical file, `hFileSize
889 -- hdl' returns the size of `hdl' in terms of the number of items
890 -- which can be read from `hdl'.
892 hFileSize :: Handle -> IO Integer
894 withHandle_ "hFileSize" handle $ \ handle_ -> do
895 case haType handle_ of
896 ClosedHandle -> ioe_closedHandle
897 SemiClosedHandle -> ioe_closedHandle
898 _ -> do flushWriteBufferOnly handle_
899 r <- fdFileSize (haFD handle_)
902 else ioException (IOError Nothing InappropriateType "hFileSize"
903 "not a regular file" Nothing)
905 -- ---------------------------------------------------------------------------
906 -- Detecting the End of Input
908 -- For a readable handle `hdl', `hIsEOF hdl' returns
909 -- `True' if no further input can be taken from `hdl' or for a
910 -- physical file, if the current I/O position is equal to the length of
911 -- the file. Otherwise, it returns `False'.
913 hIsEOF :: Handle -> IO Bool
916 (do hLookAhead handle; return False)
917 (\e -> if isEOFError e then return True else ioError e)
922 -- ---------------------------------------------------------------------------
925 -- hLookahead returns the next character from the handle without
926 -- removing it from the input buffer, blocking until a character is
929 hLookAhead :: Handle -> IO Char
930 hLookAhead handle = do
931 wantReadableHandle "hLookAhead" handle $ \handle_ -> do
932 let ref = haBuffer handle_
934 is_line = haBufferMode handle_ == LineBuffering
937 -- fill up the read buffer if necessary
938 new_buf <- if bufferEmpty buf
939 then fillReadBuffer fd is_line (haIsStream handle_) buf
942 writeIORef ref new_buf
944 (c,_) <- readCharFromBuffer (bufBuf buf) (bufRPtr buf)
947 -- ---------------------------------------------------------------------------
948 -- Buffering Operations
950 -- Three kinds of buffering are supported: line-buffering,
951 -- block-buffering or no-buffering. See GHC.IOBase for definition and
952 -- further explanation of what the type represent.
954 -- Computation `hSetBuffering hdl mode' sets the mode of buffering for
955 -- handle hdl on subsequent reads and writes.
957 -- * If mode is LineBuffering, line-buffering should be enabled if possible.
959 -- * If mode is `BlockBuffering size', then block-buffering
960 -- should be enabled if possible. The size of the buffer is n items
961 -- if size is `Just n' and is otherwise implementation-dependent.
963 -- * If mode is NoBuffering, then buffering is disabled if possible.
965 -- If the buffer mode is changed from BlockBuffering or
966 -- LineBuffering to NoBuffering, then any items in the output
967 -- buffer are written to the device, and any items in the input buffer
968 -- are discarded. The default buffering mode when a handle is opened
969 -- is implementation-dependent and may depend on the object which is
970 -- attached to that handle.
972 hSetBuffering :: Handle -> BufferMode -> IO ()
973 hSetBuffering handle mode =
974 withAllHandles__ "hSetBuffering" handle $ \ handle_ -> do
975 case haType handle_ of
976 ClosedHandle -> ioe_closedHandle
979 - we flush the old buffer regardless of whether
980 the new buffer could fit the contents of the old buffer
982 - allow a handle's buffering to change even if IO has
983 occurred (ANSI C spec. does not allow this, nor did
984 the previous implementation of IO.hSetBuffering).
985 - a non-standard extension is to allow the buffering
986 of semi-closed handles to change [sof 6/98]
990 let state = initBufferState (haType handle_)
993 -- we always have a 1-character read buffer for
994 -- unbuffered handles: it's needed to
995 -- support hLookAhead.
996 NoBuffering -> allocateBuffer 1 ReadBuffer
997 LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state
998 BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state
999 BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n
1000 | otherwise -> allocateBuffer n state
1001 writeIORef (haBuffer handle_) new_buf
1003 -- for input terminals we need to put the terminal into
1004 -- cooked or raw mode depending on the type of buffering.
1005 is_tty <- fdIsTTY (haFD handle_)
1006 when (is_tty && isReadableHandleType (haType handle_)) $
1008 #ifndef mingw32_TARGET_OS
1009 -- 'raw' mode under win32 is a bit too specialised (and troublesome
1010 -- for most common uses), so simply disable its use here.
1011 NoBuffering -> setCooked (haFD handle_) False
1013 _ -> setCooked (haFD handle_) True
1015 -- throw away spare buffers, they might be the wrong size
1016 writeIORef (haBuffers handle_) BufferListNil
1018 return (handle_{ haBufferMode = mode })
1020 -- -----------------------------------------------------------------------------
1023 -- The action `hFlush hdl' causes any items buffered for output
1024 -- in handle `hdl' to be sent immediately to the operating
1027 hFlush :: Handle -> IO ()
1029 wantWritableHandle "hFlush" handle $ \ handle_ -> do
1030 buf <- readIORef (haBuffer handle_)
1031 if bufferIsWritable buf && not (bufferEmpty buf)
1032 then do flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf
1033 writeIORef (haBuffer handle_) flushed_buf
1037 -- -----------------------------------------------------------------------------
1038 -- Repositioning Handles
1040 data HandlePosn = HandlePosn Handle HandlePosition
1042 instance Eq HandlePosn where
1043 (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2
1045 instance Show HandlePosn where
1046 showsPrec p (HandlePosn h pos) =
1047 showsPrec p h . showString " at position " . shows pos
1049 -- HandlePosition is the Haskell equivalent of POSIX' off_t.
1050 -- We represent it as an Integer on the Haskell side, but
1051 -- cheat slightly in that hGetPosn calls upon a C helper
1052 -- that reports the position back via (merely) an Int.
1053 type HandlePosition = Integer
1055 -- Computation `hGetPosn hdl' returns the current I/O position of
1056 -- `hdl' as an abstract position. Computation `hSetPosn p' sets the
1057 -- position of `hdl' to a previously obtained position `p'.
1059 hGetPosn :: Handle -> IO HandlePosn
1060 hGetPosn handle = do
1061 posn <- hTell handle
1062 return (HandlePosn handle posn)
1064 hSetPosn :: HandlePosn -> IO ()
1065 hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i
1067 -- ---------------------------------------------------------------------------
1071 The action `hSeek hdl mode i' sets the position of handle
1072 `hdl' depending on `mode'. If `mode' is
1074 * AbsoluteSeek - The position of `hdl' is set to `i'.
1075 * RelativeSeek - The position of `hdl' is set to offset `i' from
1076 the current position.
1077 * SeekFromEnd - The position of `hdl' is set to offset `i' from
1078 the end of the file.
1080 Some handles may not be seekable (see `hIsSeekable'), or only
1081 support a subset of the possible positioning operations (e.g. it may
1082 only be possible to seek to the end of a tape, or to a positive
1083 offset from the beginning or current position).
1085 It is not possible to set a negative I/O position, or for a physical
1086 file, an I/O position beyond the current end-of-file.
1089 - when seeking using `SeekFromEnd', positive offsets (>=0) means
1090 seeking at or past EOF.
1092 - we possibly deviate from the report on the issue of seeking within
1093 the buffer and whether to flush it or not. The report isn't exactly
1097 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
1098 deriving (Eq, Ord, Ix, Enum, Read, Show)
1100 hSeek :: Handle -> SeekMode -> Integer -> IO ()
1101 hSeek handle mode offset =
1102 wantSeekableHandle "hSeek" handle $ \ handle_ -> do
1104 puts ("hSeek " ++ show (mode,offset) ++ "\n")
1106 let ref = haBuffer handle_
1107 buf <- readIORef ref
1113 throwErrnoIfMinus1Retry_ "hSeek"
1114 (c_lseek (fromIntegral (haFD handle_)) (fromIntegral offset) whence)
1117 whence = case mode of
1118 AbsoluteSeek -> sEEK_SET
1119 RelativeSeek -> sEEK_CUR
1120 SeekFromEnd -> sEEK_END
1122 if bufferIsWritable buf
1123 then do new_buf <- flushWriteBuffer fd (haIsStream handle_) buf
1124 writeIORef ref new_buf
1128 if mode == RelativeSeek && offset >= 0 && offset < fromIntegral (w - r)
1129 then writeIORef ref buf{ bufRPtr = r + fromIntegral offset }
1132 new_buf <- flushReadBuffer (haFD handle_) buf
1133 writeIORef ref new_buf
1137 hTell :: Handle -> IO Integer
1139 wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do
1141 #if defined(mingw32_TARGET_OS)
1142 -- urgh, on Windows we have to worry about \n -> \r\n translation,
1143 -- so we can't easily calculate the file position using the
1144 -- current buffer size. Just flush instead.
1147 let fd = fromIntegral (haFD handle_)
1148 posn <- fromIntegral `liftM`
1149 throwErrnoIfMinus1Retry "hGetPosn"
1150 (c_lseek fd 0 sEEK_CUR)
1152 let ref = haBuffer handle_
1153 buf <- readIORef ref
1156 | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf)
1157 | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf)
1159 puts ("\nhGetPosn: (fd, posn, real_posn) = " ++ show (fd, posn, real_posn) ++ "\n")
1160 puts (" (bufWPtr, bufRPtr) = " ++ show (bufWPtr buf, bufRPtr buf) ++ "\n")
1164 -- -----------------------------------------------------------------------------
1165 -- Handle Properties
1167 -- A number of operations return information about the properties of a
1168 -- handle. Each of these operations returns `True' if the handle has
1169 -- the specified property, and `False' otherwise.
1171 hIsOpen :: Handle -> IO Bool
1173 withHandle_ "hIsOpen" handle $ \ handle_ -> do
1174 case haType handle_ of
1175 ClosedHandle -> return False
1176 SemiClosedHandle -> return False
1179 hIsClosed :: Handle -> IO Bool
1181 withHandle_ "hIsClosed" handle $ \ handle_ -> do
1182 case haType handle_ of
1183 ClosedHandle -> return True
1186 {- not defined, nor exported, but mentioned
1187 here for documentation purposes:
1189 hSemiClosed :: Handle -> IO Bool
1193 return (not (ho || hc))
1196 hIsReadable :: Handle -> IO Bool
1197 hIsReadable (DuplexHandle _ _ _) = return True
1198 hIsReadable handle =
1199 withHandle_ "hIsReadable" handle $ \ handle_ -> do
1200 case haType handle_ of
1201 ClosedHandle -> ioe_closedHandle
1202 SemiClosedHandle -> ioe_closedHandle
1203 htype -> return (isReadableHandleType htype)
1205 hIsWritable :: Handle -> IO Bool
1206 hIsWritable (DuplexHandle _ _ _) = return True
1207 hIsWritable handle =
1208 withHandle_ "hIsWritable" handle $ \ handle_ -> do
1209 case haType handle_ of
1210 ClosedHandle -> ioe_closedHandle
1211 SemiClosedHandle -> ioe_closedHandle
1212 htype -> return (isWritableHandleType htype)
1214 -- Querying how a handle buffers its data:
1216 hGetBuffering :: Handle -> IO BufferMode
1217 hGetBuffering handle =
1218 withHandle_ "hGetBuffering" handle $ \ handle_ -> do
1219 case haType handle_ of
1220 ClosedHandle -> ioe_closedHandle
1222 -- We're being non-standard here, and allow the buffering
1223 -- of a semi-closed handle to be queried. -- sof 6/98
1224 return (haBufferMode handle_) -- could be stricter..
1226 hIsSeekable :: Handle -> IO Bool
1227 hIsSeekable handle =
1228 withHandle_ "hIsSeekable" handle $ \ handle_ -> do
1229 case haType handle_ of
1230 ClosedHandle -> ioe_closedHandle
1231 SemiClosedHandle -> ioe_closedHandle
1232 AppendHandle -> return False
1233 _ -> do t <- fdType (haFD handle_)
1234 return (t == RegularFile
1236 || tEXT_MODE_SEEK_ALLOWED))
1238 -- -----------------------------------------------------------------------------
1239 -- Changing echo status (Non-standard GHC extensions)
1241 -- | Set the echoing status of a handle connected to a terminal (GHC only).
1243 hSetEcho :: Handle -> Bool -> IO ()
1244 hSetEcho handle on = do
1245 isT <- hIsTerminalDevice handle
1249 withHandle_ "hSetEcho" handle $ \ handle_ -> do
1250 case haType handle_ of
1251 ClosedHandle -> ioe_closedHandle
1252 _ -> setEcho (haFD handle_) on
1254 -- | Get the echoing status of a handle connected to a terminal (GHC only).
1256 hGetEcho :: Handle -> IO Bool
1257 hGetEcho handle = do
1258 isT <- hIsTerminalDevice handle
1262 withHandle_ "hGetEcho" handle $ \ handle_ -> do
1263 case haType handle_ of
1264 ClosedHandle -> ioe_closedHandle
1265 _ -> getEcho (haFD handle_)
1267 -- | Is the handle connected to a terminal? (GHC only)
1269 hIsTerminalDevice :: Handle -> IO Bool
1270 hIsTerminalDevice handle = do
1271 withHandle_ "hIsTerminalDevice" handle $ \ handle_ -> do
1272 case haType handle_ of
1273 ClosedHandle -> ioe_closedHandle
1274 _ -> fdIsTTY (haFD handle_)
1276 -- -----------------------------------------------------------------------------
1279 -- | On Windows, reading a file in text mode (which is the default) will
1280 -- translate CRLF to LF, and writing will translate LF to CRLF. This
1281 -- is usually what you want with text files. With binary files this is
1282 -- undesirable; also, as usual under Microsoft operating systems, text
1283 -- mode treats control-Z as EOF. Setting binary mode using
1284 -- 'hSetBinaryMode' turns off all special treatment of end-of-line and
1285 -- end-of-file characters.
1287 hSetBinaryMode :: Handle -> Bool -> IO ()
1288 hSetBinaryMode handle bin =
1289 withAllHandles__ "hSetBinaryMode" handle $ \ handle_ ->
1290 do throwErrnoIfMinus1_ "hSetBinaryMode"
1291 (setmode (fromIntegral (haFD handle_)) bin)
1292 return handle_{haIsBin=bin}
1294 foreign import ccall unsafe "__hscore_setmode"
1295 setmode :: CInt -> Bool -> IO CInt
1297 -- -----------------------------------------------------------------------------
1298 -- Duplicating a Handle
1300 -- |Returns a duplicate of the original handle, with its own buffer
1301 -- and file pointer. The original handle's buffer is flushed, including
1302 -- discarding any input data, before the handle is duplicated.
1304 hDuplicate :: Handle -> IO Handle
1305 hDuplicate h@(FileHandle path m) = do
1306 new_h_ <- withHandle' "hDuplicate" h m (dupHandle_ Nothing)
1307 new_m <- newMVar new_h_
1308 return (FileHandle path new_m)
1309 hDuplicate h@(DuplexHandle path r w) = do
1310 new_w_ <- withHandle' "hDuplicate" h w (dupHandle_ Nothing)
1311 new_w <- newMVar new_w_
1312 new_r_ <- withHandle' "hDuplicate" h r (dupHandle_ (Just new_w))
1313 new_r <- newMVar new_r_
1314 return (DuplexHandle path new_r new_w)
1316 dupHandle_ other_side h_ = do
1317 -- flush the buffer first, so we don't have to copy its contents
1319 new_fd <- c_dup (fromIntegral (haFD h_))
1320 buffer <- allocateBuffer dEFAULT_BUFFER_SIZE (initBufferState (haType h_))
1321 ioref <- newIORef buffer
1322 ioref_buffers <- newIORef BufferListNil
1324 let new_handle_ = h_{ haFD = fromIntegral new_fd,
1326 haBuffers = ioref_buffers,
1327 haOtherSide = other_side }
1328 return (h_, new_handle_)
1330 -- -----------------------------------------------------------------------------
1331 -- Replacing a Handle
1334 Makes the second handle a duplicate of the first handle. The second
1335 handle will be closed first, if it is not already.
1337 This can be used to retarget the standard Handles, for example:
1339 > do h <- openFile "mystdout" WriteMode
1340 > hDuplicateTo h stdout
1343 hDuplicateTo :: Handle -> Handle -> IO ()
1344 hDuplicateTo h1@(FileHandle _ m1) h2@(FileHandle _ m2) = do
1345 withHandle__' "hDuplicateTo" h2 m2 $ \h2_ -> do
1346 _ <- hClose_help h2_
1347 withHandle' "hDuplicateTo" h1 m1 (dupHandle_ Nothing)
1348 hDuplicateTo h1@(DuplexHandle _ r1 w1) h2@(DuplexHandle _ r2 w2) = do
1349 withHandle__' "hDuplicateTo" h2 w2 $ \w2_ -> do
1350 _ <- hClose_help w2_
1351 withHandle' "hDuplicateTo" h1 r1 (dupHandle_ Nothing)
1352 withHandle__' "hDuplicateTo" h2 r2 $ \r2_ -> do
1353 _ <- hClose_help r2_
1354 withHandle' "hDuplicateTo" h1 r1 (dupHandle_ (Just w1))
1356 ioException (IOError (Just h1) IllegalOperation "hDuplicateTo"
1357 "handles are incompatible" Nothing)
1359 -- ---------------------------------------------------------------------------
1362 -- hShow is in the IO monad, and gives more comprehensive output
1363 -- than the (pure) instance of Show for Handle.
1365 hShow :: Handle -> IO String
1366 hShow h@(FileHandle path _) = showHandle' path False h
1367 hShow h@(DuplexHandle path _ _) = showHandle' path True h
1369 showHandle' filepath is_duplex h =
1370 withHandle_ "showHandle" h $ \hdl_ ->
1372 showType | is_duplex = showString "duplex (read-write)"
1373 | otherwise = shows (haType hdl_)
1377 showHdl (haType hdl_)
1378 (showString "loc=" . showString filepath . showChar ',' .
1379 showString "type=" . showType . showChar ',' .
1380 showString "binary=" . shows (haIsBin hdl_) . showChar ',' .
1381 showString "buffering=" . showBufMode (unsafePerformIO (readIORef (haBuffer hdl_))) (haBufferMode hdl_) . showString "}" )
1385 showHdl :: HandleType -> ShowS -> ShowS
1388 ClosedHandle -> shows ht . showString "}"
1391 showBufMode :: Buffer -> BufferMode -> ShowS
1392 showBufMode buf bmo =
1394 NoBuffering -> showString "none"
1395 LineBuffering -> showString "line"
1396 BlockBuffering (Just n) -> showString "block " . showParen True (shows n)
1397 BlockBuffering Nothing -> showString "block " . showParen True (shows def)
1402 -- ---------------------------------------------------------------------------
1406 puts :: String -> IO ()
1407 puts s = withCString s $ \cstr -> do write_rawBuffer 1 False cstr 0 (fromIntegral (length s))
1411 -- -----------------------------------------------------------------------------
1412 -- wrappers to platform-specific constants:
1414 foreign import ccall unsafe "__hscore_supportsTextMode"
1415 tEXT_MODE_SEEK_ALLOWED :: Bool
1417 foreign import ccall unsafe "__hscore_bufsiz" dEFAULT_BUFFER_SIZE :: Int
1418 foreign import ccall unsafe "__hscore_seek_cur" sEEK_CUR :: CInt
1419 foreign import ccall unsafe "__hscore_seek_set" sEEK_SET :: CInt
1420 foreign import ccall unsafe "__hscore_seek_end" sEEK_END :: CInt