2 % (c) The GRAP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrelIO]{Module @PrelIO@}
6 This module defines all basic IO operations.
7 These are needed for the IO operations exported by Prelude,
8 but as it happens they also do everything required by library
13 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
20 import PrelHandle -- much of the real stuff is in here
22 import PrelRead ( readParen, Read(..), reads, lex,
26 import PrelMaybe ( Either(..), Maybe(..) )
27 import PrelAddr ( Addr(..), nullAddr )
28 import PrelByteArr ( ByteArray )
29 import PrelPack ( unpackNBytesAccST )
30 import PrelException ( ioError, catch )
36 %*********************************************************
38 \subsection{Standard IO}
40 %*********************************************************
42 The Prelude has from Day 1 provided a collection of common
43 IO functions. We define these here, but let the Prelude
47 putChar :: Char -> IO ()
48 putChar c = hPutChar stdout c
50 putStr :: String -> IO ()
51 putStr s = hPutStr stdout s
53 putStrLn :: String -> IO ()
54 putStrLn s = do putStr s
57 print :: Show a => a -> IO ()
58 print x = putStrLn (show x)
61 getChar = hGetChar stdin
64 getLine = hGetLine stdin
66 getContents :: IO String
67 getContents = hGetContents stdin
69 interact :: (String -> String) -> IO ()
70 interact f = do s <- getContents
73 readFile :: FilePath -> IO String
74 readFile name = openFile name ReadMode >>= hGetContents
76 writeFile :: FilePath -> String -> IO ()
77 writeFile name str = do
78 hdl <- openFile name WriteMode
82 appendFile :: FilePath -> String -> IO ()
83 appendFile name str = do
84 hdl <- openFile name AppendMode
88 readLn :: Read a => IO a
89 readLn = do l <- getLine
95 %*********************************************************
97 \subsection{Simple input operations}
99 %*********************************************************
101 Computation @hReady hdl@ indicates whether at least
102 one item is available for input from handle {\em hdl}.
104 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
105 before deciding whether the Handle has run dry or not.
107 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
108 If not, it tries to read from the underlying OS handle. Notice that
109 for buffered Handles connected to terminals this means waiting until a complete
113 hReady :: Handle -> IO Bool
114 hReady h = hWaitForInput h 0
116 hWaitForInput :: Handle -> Int -> IO Bool
117 hWaitForInput handle msecs =
118 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
119 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
123 _ -> constructErrorAndFail "hWaitForInput"
126 @hGetChar hdl@ reads the next character from handle @hdl@,
127 blocking until a character is available.
130 hGetChar :: Handle -> IO Char
132 c <- mayBlockRead "hGetChar" handle fileGetc
136 If EOF is reached before EOL is encountered, ignore the
137 EOF and return the partial line. Next attempt at calling
138 hGetLine on the handle will yield an EOF IO exception though.
140 hGetLine :: Handle -> IO String
154 if isEOFError err then
166 @hLookahead hdl@ returns the next character from handle @hdl@
167 without removing it from the input buffer, blocking until a
168 character is available.
171 hLookAhead :: Handle -> IO Char
172 hLookAhead handle = do
173 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
178 %*********************************************************
180 \subsection{Getting the entire contents of a handle}
182 %*********************************************************
184 @hGetContents hdl@ returns the list of characters corresponding
185 to the unread portion of the channel or file managed by @hdl@,
186 which is made semi-closed.
189 hGetContents :: Handle -> IO String
190 hGetContents handle =
191 -- can't use wantReadableHandle here, because we want to side effect
193 withHandle handle $ \ handle_ -> do
194 case haType__ handle_ of
195 ErrorHandle theError -> ioError theError
196 ClosedHandle -> ioe_closedHandle "hGetContents" handle
197 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
198 AppendHandle -> ioError not_readable_error
199 WriteHandle -> ioError not_readable_error
202 To avoid introducing an extra layer of buffering here,
203 we provide three lazy read methods, based on character,
204 line, and block buffering.
206 let handle_' = handle_{ haType__ = SemiClosedHandle }
207 case (haBufferMode__ handle_) of
209 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
210 return (handle_', str)
211 BlockBuffering _ -> do
212 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
213 return (handle_', str)
215 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
216 return (handle_', str)
219 IOError (Just handle) IllegalOperation "hGetContents"
220 ("handle is not open for reading")
223 Note that someone may close the semi-closed handle (or change its buffering),
224 so each these lazy read functions are pulled on, they have to check whether
225 the handle has indeed been closed.
228 #ifndef __PARALLEL_HASKELL__
229 lazyReadBlock :: Handle -> ForeignObj -> IO String
230 lazyReadLine :: Handle -> ForeignObj -> IO String
231 lazyReadChar :: Handle -> ForeignObj -> IO String
233 lazyReadBlock :: Handle -> Addr -> IO String
234 lazyReadLine :: Handle -> Addr -> IO String
235 lazyReadChar :: Handle -> Addr -> IO String
238 lazyReadBlock handle fo = do
239 buf <- getBufStart fo 0
240 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
242 -3 -> -- buffering has been turned off, use lazyReadChar instead
243 lazyReadChar handle fo
245 -1 -> -- an error occurred, close the handle
246 withHandle handle $ \ handle_ -> do
247 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
248 return (handle_ { haType__ = ClosedHandle,
249 haFO__ = nullFile__ },
252 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
253 stToIO (unpackNBytesAccST buf bytes more)
255 lazyReadLine handle fo = do
256 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
258 -3 -> -- buffering has been turned off, use lazyReadChar instead
259 lazyReadChar handle fo
260 -2 -> return "" -- handle closed by someone else, stop reading.
261 -1 -> -- an error occurred, close the handle
262 withHandle handle $ \ handle_ -> do
263 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
264 return (handle_ { haType__ = ClosedHandle,
265 haFO__ = nullFile__ },
268 more <- unsafeInterleaveIO (lazyReadLine handle fo)
269 buf <- getBufStart fo bytes -- ConcHask: won't block
270 stToIO (unpackNBytesAccST buf bytes more)
272 lazyReadChar handle fo = do
273 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
275 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
276 lazyReadBlock handle fo
278 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
279 lazyReadLine handle fo
281 -1 -> -- error, silently close handle.
282 withHandle handle $ \ handle_ -> do
283 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
284 return (handle_{ haType__ = ClosedHandle,
285 haFO__ = nullFile__ },
288 more <- unsafeInterleaveIO (lazyReadChar handle fo)
289 return (chr char : more)
294 %*********************************************************
296 \subsection{Simple output functions}
298 %*********************************************************
300 @hPutChar hdl ch@ writes the character @ch@ to the file
301 or channel managed by @hdl@. Characters may be buffered if
302 buffering is enabled for @hdl@
305 hPutChar :: Handle -> Char -> IO ()
307 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
308 let fo = haFO__ handle_
310 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
313 else constructErrorAndFail "hPutChar"
317 @hPutStr hdl s@ writes the string @s@ to the file or
318 channel managed by @hdl@, buffering the output if needs be.
321 hPutStr :: Handle -> String -> IO ()
323 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
324 let fo = haFO__ handle_
326 case haBufferMode__ handle_ of
328 buf <- getWriteableBuf fo
331 writeLines fo buf bsz pos str
332 BlockBuffering _ -> do
333 buf <- getWriteableBuf fo
336 writeBlocks fo buf bsz pos str
341 Going across the border between Haskell and C is relatively costly,
342 so for block writes we pack the character strings on the Haskell-side
343 before passing the external write routine a pointer to the buffer.
348 #ifdef __CONCURRENT_HASKELL__
349 /* See comment in shoveString below for explanation */
350 #warning delayed update of buffer disnae work with killThread
353 #ifndef __PARALLEL_HASKELL__
354 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
356 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
358 writeLines obj buf bufLen initPos s =
360 shoveString :: Int -> [Char] -> IO ()
365 At the end of a buffer write, update the buffer position
366 in the underlying file object, so that if the handle
367 is subsequently dropped by the program, the whole
368 buffer will be properly flushed.
370 There's one case where this delayed up-date of the buffer
371 position can go wrong: if a thread is killed, it might be
372 in the middle of filling up a buffer, with the result that
373 the partial buffer update is lost upon finalisation. Not
374 that killing of threads is supported at the moment.
380 primWriteCharOffAddr buf n x
381 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
382 if n == bufLen || x == '\n'
384 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
386 then shoveString 0 xs
387 else constructErrorAndFail "writeLines"
389 shoveString (n + 1) xs
391 shoveString initPos s
392 #else /* ndef __HUGS__ */
393 #ifndef __PARALLEL_HASKELL__
394 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
396 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
398 writeLines obj buf (I# bufLen) (I# initPos#) s =
400 write_char :: Addr -> Int# -> Char# -> IO ()
401 write_char (A# buf#) n# c# =
403 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
405 shoveString :: Int# -> [Char] -> IO ()
410 At the end of a buffer write, update the buffer position
411 in the underlying file object, so that if the handle
412 is subsequently dropped by the program, the whole
413 buffer will be properly flushed.
415 There's one case where this delayed up-date of the buffer
416 position can go wrong: if a thread is killed, it might be
417 in the middle of filling up a buffer, with the result that
418 the partial buffer update is lost upon finalisation. Not
419 that killing of threads is supported at the moment.
422 setBufWPtr obj (I# n)
426 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
427 if n ==# bufLen || x `eqChar#` '\n'#
429 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
431 then shoveString 0# xs
432 else constructErrorAndFail "writeLines"
434 shoveString (n +# 1#) xs
436 shoveString initPos# s
437 #endif /* ndef __HUGS__ */
440 #ifndef __PARALLEL_HASKELL__
441 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
443 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
445 writeBlocks obj buf bufLen initPos s =
447 shoveString :: Int -> [Char] -> IO ()
452 At the end of a buffer write, update the buffer position
453 in the underlying file object, so that if the handle
454 is subsequently dropped by the program, the whole
455 buffer will be properly flushed.
457 There's one case where this delayed up-date of the buffer
458 position can go wrong: if a thread is killed, it might be
459 in the middle of filling up a buffer, with the result that
460 the partial buffer update is lost upon finalisation. However,
461 by the time killThread is supported, Haskell finalisers are also
462 likely to be in, which means the 'IOFileObject' hack can go
469 primWriteCharOffAddr buf n x
472 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
474 then shoveString 0 xs
475 else constructErrorAndFail "writeChunks"
477 shoveString (n + 1) xs
479 shoveString initPos s
480 #else /* ndef __HUGS__ */
481 #ifndef __PARALLEL_HASKELL__
482 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
484 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
486 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
488 write_char :: Addr -> Int# -> Char# -> IO ()
489 write_char (A# buf#) n# c# =
491 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
493 shoveString :: Int# -> [Char] -> IO ()
498 At the end of a buffer write, update the buffer position
499 in the underlying file object, so that if the handle
500 is subsequently dropped by the program, the whole
501 buffer will be properly flushed.
503 There's one case where this delayed up-date of the buffer
504 position can go wrong: if a thread is killed, it might be
505 in the middle of filling up a buffer, with the result that
506 the partial buffer update is lost upon finalisation. However,
507 by the time killThread is supported, Haskell finalisers are also
508 likely to be in, which means the 'IOFileObject' hack can go
512 setBufWPtr obj (I# n)
518 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
520 then shoveString 0# xs
521 else constructErrorAndFail "writeChunks"
523 shoveString (n +# 1#) xs
525 shoveString initPos# s
526 #endif /* ndef __HUGS__ */
528 #ifndef __PARALLEL_HASKELL__
529 writeChars :: ForeignObj -> String -> IO ()
531 writeChars :: Addr -> String -> IO ()
533 writeChars _fo "" = return ()
534 writeChars fo (c:cs) = do
535 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
537 then writeChars fo cs
538 else constructErrorAndFail "writeChars"
542 Computation @hPrint hdl t@ writes the string representation of {\em t}
543 given by the @shows@ function to the file or channel managed by {\em
546 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
549 hPrint :: Show a => Handle -> a -> IO ()
550 hPrint hdl = hPutStrLn hdl . show
553 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
554 the handle \tr{hdl}, adding a newline at the end.
557 hPutStrLn :: Handle -> String -> IO ()
558 hPutStrLn hndl str = do