4 , ForeignFunctionInterface
7 {-# OPTIONS_GHC -fno-warn-identities #-}
8 -- Whether there are identities depends on the platform
9 {-# OPTIONS_HADDOCK hide #-}
11 -----------------------------------------------------------------------------
14 -- Copyright : (c) The University of Glasgow, 1994-2008
15 -- License : see libraries/base/LICENSE
17 -- Maintainer : libraries@haskell.org
18 -- Stability : internal
19 -- Portability : non-portable
21 -- Raw read/write operations on file descriptors
23 -----------------------------------------------------------------------------
27 openFile, mkFD, release,
29 readRawBufferPtr, readRawBufferPtrNoBlock, writeRawBufferPtr,
45 import GHC.IO.BufferedIO
46 import qualified GHC.IO.Device
47 import GHC.IO.Device (SeekMode(..), IODeviceType(..))
49 import GHC.IO.Exception
53 import qualified System.Posix.Internals
54 import System.Posix.Internals hiding (FD, setEcho, getEcho)
55 import System.Posix.Types
61 -- -----------------------------------------------------------------------------
62 -- The file-descriptor IO device
65 fdFD :: {-# UNPACK #-} !CInt,
66 #ifdef mingw32_HOST_OS
67 -- On Windows, a socket file descriptor needs to be read and written
68 -- using different functions (send/recv).
69 fdIsSocket_ :: {-# UNPACK #-} !Int
71 -- On Unix we need to know whether this FD has O_NONBLOCK set.
72 -- If it has, then we can use more efficient routines to read/write to it.
73 -- It is always safe for this to be off.
74 fdIsNonBlocking :: {-# UNPACK #-} !Int
79 #ifdef mingw32_HOST_OS
80 fdIsSocket :: FD -> Bool
81 fdIsSocket fd = fdIsSocket_ fd /= 0
84 instance Show FD where
85 show fd = show (fdFD fd)
87 instance GHC.IO.Device.RawIO FD where
89 readNonBlocking = fdReadNonBlocking
91 writeNonBlocking = fdWriteNonBlocking
93 instance GHC.IO.Device.IODevice FD where
96 isTerminal = isTerminal
97 isSeekable = isSeekable
109 -- We used to use System.Posix.Internals.dEFAULT_BUFFER_SIZE, which is
110 -- taken from the value of BUFSIZ on the current platform. This value
111 -- varies too much though: it is 512 on Windows, 1024 on OS X and 8192
112 -- on Linux. So let's just use a decent size on every platform:
113 dEFAULT_FD_BUFFER_SIZE :: Int
114 dEFAULT_FD_BUFFER_SIZE = 8096
116 instance BufferedIO FD where
117 newBuffer _dev state = newByteBuffer dEFAULT_FD_BUFFER_SIZE state
118 fillReadBuffer fd buf = readBuf' fd buf
119 fillReadBuffer0 fd buf = readBufNonBlocking fd buf
120 flushWriteBuffer fd buf = writeBuf' fd buf
121 flushWriteBuffer0 fd buf = writeBufNonBlocking fd buf
123 readBuf' :: FD -> Buffer Word8 -> IO (Int, Buffer Word8)
126 puts ("readBuf fd=" ++ show fd ++ " " ++ summaryBuffer buf ++ "\n")
127 (r,buf') <- readBuf fd buf
129 puts ("after: " ++ summaryBuffer buf' ++ "\n")
132 writeBuf' :: FD -> Buffer Word8 -> IO (Buffer Word8)
133 writeBuf' fd buf = do
135 puts ("writeBuf fd=" ++ show fd ++ " " ++ summaryBuffer buf ++ "\n")
138 -- -----------------------------------------------------------------------------
141 -- | Open a file and make an 'FD' for it. Truncates the file to zero
142 -- size when the `IOMode` is `WriteMode`. Puts the file descriptor
143 -- into non-blocking mode on Unix systems.
144 openFile :: FilePath -> IOMode -> Bool -> IO (FD,IODeviceType)
145 openFile filepath iomode non_blocking =
146 withFilePath filepath $ \ f ->
149 oflags1 = case iomode of
150 ReadMode -> read_flags
151 #ifdef mingw32_HOST_OS
152 WriteMode -> write_flags .|. o_TRUNC
154 WriteMode -> write_flags
156 ReadWriteMode -> rw_flags
157 AppendMode -> append_flags
159 #ifdef mingw32_HOST_OS
160 binary_flags = o_BINARY
165 oflags2 = oflags1 .|. binary_flags
167 oflags | non_blocking = oflags2 .|. nonblock_flags
168 | otherwise = oflags2
171 -- the old implementation had a complicated series of three opens,
172 -- which is perhaps because we have to be careful not to open
173 -- directories. However, the man pages I've read say that open()
174 -- always returns EISDIR if the file is a directory and was opened
175 -- for writing, so I think we're ok with a single open() here...
176 fd <- throwErrnoIfMinus1Retry "openFile"
177 (if non_blocking then c_open f oflags 0o666
178 else c_safe_open f oflags 0o666)
180 (fD,fd_type) <- mkFD fd iomode Nothing{-no stat-}
181 False{-not a socket-}
183 `catchAny` \e -> do _ <- c_close fd
186 #ifndef mingw32_HOST_OS
187 -- we want to truncate() if this is an open in WriteMode, but only
188 -- if the target is a RegularFile. ftruncate() fails on special files
190 if iomode == WriteMode && fd_type == RegularFile
197 std_flags, output_flags, read_flags, write_flags, rw_flags,
198 append_flags, nonblock_flags :: CInt
200 output_flags = std_flags .|. o_CREAT
201 read_flags = std_flags .|. o_RDONLY
202 write_flags = output_flags .|. o_WRONLY
203 rw_flags = output_flags .|. o_RDWR
204 append_flags = write_flags .|. o_APPEND
205 nonblock_flags = o_NONBLOCK
208 -- | Make a 'FD' from an existing file descriptor. Fails if the FD
209 -- refers to a directory. If the FD refers to a file, `mkFD` locks
210 -- the file according to the Haskell 98 single writer/multiple reader
211 -- locking semantics (this is why we need the `IOMode` argument too).
214 -> Maybe (IODeviceType, CDev, CIno)
215 -- the results of fdStat if we already know them, or we want
216 -- to prevent fdToHandle_stat from doing its own stat.
217 -- These are used for:
218 -- - we fail if the FD refers to a directory
219 -- - if the FD refers to a file, we lock it using (cdev,cino)
220 -> Bool -- ^ is a socket (on Windows)
221 -> Bool -- ^ is in non-blocking mode on Unix
222 -> IO (FD,IODeviceType)
224 mkFD fd iomode mb_stat is_socket is_nonblock = do
226 let _ = (is_socket, is_nonblock) -- warning suppression
231 Just stat -> return stat
233 let write = case iomode of
237 #ifdef mingw32_HOST_OS
238 _ <- setmode fd True -- unconditionally set binary mode
239 let _ = (dev,ino,write) -- warning suppression
244 ioException (IOError Nothing InappropriateType "openFile"
245 "is a directory" Nothing Nothing)
247 #ifndef mingw32_HOST_OS
248 -- regular files need to be locked
250 -- On Windows we use explicit exclusion via sopen() to implement
251 -- this locking (see __hscore_open()); on Unix we have to
252 -- implment it in the RTS.
253 r <- lockFile fd dev ino (fromBool write)
255 ioException (IOError Nothing ResourceBusy "openFile"
256 "file is locked" Nothing Nothing)
259 _other_type -> return ()
261 return (FD{ fdFD = fd,
262 #ifndef mingw32_HOST_OS
263 fdIsNonBlocking = fromEnum is_nonblock
265 fdIsSocket_ = fromEnum is_socket
270 #ifdef mingw32_HOST_OS
271 foreign import ccall unsafe "__hscore_setmode"
272 setmode :: CInt -> Bool -> IO CInt
275 -- -----------------------------------------------------------------------------
276 -- Standard file descriptors
279 stdFD fd = FD { fdFD = fd,
280 #ifdef mingw32_HOST_OS
284 -- We don't set non-blocking mode on standard handles, because it may
285 -- confuse other applications attached to the same TTY/pipe
286 -- see Note [nonblock]
290 stdin, stdout, stderr :: FD
295 -- -----------------------------------------------------------------------------
296 -- Operations on file descriptors
300 #ifndef mingw32_HOST_OS
301 (flip finally) (release fd) $
303 do let closer realFd =
304 throwErrnoIfMinus1Retry_ "GHC.IO.FD.close" $
305 #ifdef mingw32_HOST_OS
306 if fdIsSocket fd then
307 c_closesocket (fromIntegral realFd)
310 c_close (fromIntegral realFd)
311 closeFdWith closer (fromIntegral (fdFD fd))
313 release :: FD -> IO ()
314 #ifdef mingw32_HOST_OS
315 release _ = return ()
317 release fd = do _ <- unlockFile (fdFD fd)
321 #ifdef mingw32_HOST_OS
322 foreign import stdcall unsafe "HsBase.h closesocket"
323 c_closesocket :: CInt -> IO CInt
326 isSeekable :: FD -> IO Bool
329 return (t == RegularFile || t == RawDevice)
331 seek :: FD -> SeekMode -> Integer -> IO ()
332 seek fd mode off = do
333 throwErrnoIfMinus1Retry_ "seek" $
334 c_lseek (fdFD fd) (fromIntegral off) seektype
337 seektype = case mode of
338 AbsoluteSeek -> sEEK_SET
339 RelativeSeek -> sEEK_CUR
340 SeekFromEnd -> sEEK_END
342 tell :: FD -> IO Integer
345 (throwErrnoIfMinus1Retry "hGetPosn" $
346 c_lseek (fdFD fd) 0 sEEK_CUR)
348 getSize :: FD -> IO Integer
349 getSize fd = fdFileSize (fdFD fd)
351 setSize :: FD -> Integer -> IO ()
353 throwErrnoIf_ (/=0) "GHC.IO.FD.setSize" $
354 c_ftruncate (fdFD fd) (fromIntegral size)
356 devType :: FD -> IO IODeviceType
357 devType fd = do (ty,_,_) <- fdStat (fdFD fd); return ty
361 newfd <- throwErrnoIfMinus1 "GHC.IO.FD.dup" $ c_dup (fdFD fd)
362 return fd{ fdFD = newfd }
364 dup2 :: FD -> FD -> IO FD
366 -- Windows' dup2 does not return the new descriptor, unlike Unix
367 throwErrnoIfMinus1_ "GHC.IO.FD.dup2" $
368 c_dup2 (fdFD fd) (fdFD fdto)
369 return fd{ fdFD = fdFD fdto } -- original FD, with the new fdFD
371 setNonBlockingMode :: FD -> Bool -> IO FD
372 setNonBlockingMode fd set = do
373 setNonBlockingFD (fdFD fd) set
374 #if defined(mingw32_HOST_OS)
377 return fd{ fdIsNonBlocking = fromEnum set }
380 ready :: FD -> Bool -> Int -> IO Bool
381 ready fd write msecs = do
382 r <- throwErrnoIfMinus1Retry "GHC.IO.FD.ready" $
383 fdReady (fdFD fd) (fromIntegral $ fromEnum $ write)
385 #if defined(mingw32_HOST_OS)
386 (fromIntegral $ fromEnum $ fdIsSocket fd)
390 return (toEnum (fromIntegral r))
392 foreign import ccall safe "fdReady"
393 fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt
395 -- ---------------------------------------------------------------------------
396 -- Terminal-related stuff
398 isTerminal :: FD -> IO Bool
400 #if defined(mingw32_HOST_OS)
401 is_console (fdFD fd) >>= return.toBool
403 c_isatty (fdFD fd) >>= return.toBool
406 setEcho :: FD -> Bool -> IO ()
407 setEcho fd on = System.Posix.Internals.setEcho (fdFD fd) on
409 getEcho :: FD -> IO Bool
410 getEcho fd = System.Posix.Internals.getEcho (fdFD fd)
412 setRaw :: FD -> Bool -> IO ()
413 setRaw fd raw = System.Posix.Internals.setCooked (fdFD fd) (not raw)
415 -- -----------------------------------------------------------------------------
416 -- Reading and Writing
418 fdRead :: FD -> Ptr Word8 -> Int -> IO Int
420 = do { r <- readRawBufferPtr "GHC.IO.FD.fdRead" fd ptr 0 (fromIntegral bytes)
421 ; return (fromIntegral r) }
423 fdReadNonBlocking :: FD -> Ptr Word8 -> Int -> IO (Maybe Int)
424 fdReadNonBlocking fd ptr bytes = do
425 r <- readRawBufferPtrNoBlock "GHC.IO.FD.fdReadNonBlocking" fd ptr
426 0 (fromIntegral bytes)
427 case fromIntegral r of
428 (-1) -> return (Nothing)
432 fdWrite :: FD -> Ptr Word8 -> Int -> IO ()
433 fdWrite fd ptr bytes = do
434 res <- writeRawBufferPtr "GHC.IO.FD.fdWrite" fd ptr 0 (fromIntegral bytes)
435 let res' = fromIntegral res
437 then fdWrite fd (ptr `plusPtr` res') (bytes - res')
440 -- XXX ToDo: this isn't non-blocking
441 fdWriteNonBlocking :: FD -> Ptr Word8 -> Int -> IO Int
442 fdWriteNonBlocking fd ptr bytes = do
443 res <- writeRawBufferPtrNoBlock "GHC.IO.FD.fdWriteNonBlocking" fd ptr 0
445 return (fromIntegral res)
447 -- -----------------------------------------------------------------------------
450 -- Low level routines for reading/writing to (raw)buffers:
452 #ifndef mingw32_HOST_OS
457 Unix has broken semantics when it comes to non-blocking I/O: you can
458 set the O_NONBLOCK flag on an FD, but it applies to the all other FDs
459 attached to the same underlying file, pipe or TTY; there's no way to
460 have private non-blocking behaviour for an FD. See bug #724.
462 We fix this by only setting O_NONBLOCK on FDs that we create; FDs that
463 come from external sources or are exposed externally are left in
464 blocking mode. This solution has some problems though. We can't
465 completely simulate a non-blocking read without O_NONBLOCK: several
466 cases are wrong here. The cases that are wrong:
468 * reading/writing to a blocking FD in non-threaded mode.
469 In threaded mode, we just make a safe call to read().
470 In non-threaded mode we call select() before attempting to read,
471 but that leaves a small race window where the data can be read
472 from the file descriptor before we issue our blocking read().
473 * readRawBufferNoBlock for a blocking FD
477 In the threaded RTS we could just make safe calls to read()/write()
478 for file descriptors in blocking mode without worrying about blocking
479 other threads, but the problem with this is that the thread will be
480 uninterruptible while it is blocked in the foreign call. See #2363.
481 So now we always call fdReady() before reading, and if fdReady
482 indicates that there's no data, we call threadWaitRead.
486 readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
487 readRawBufferPtr loc !fd buf off len
488 | isNonBlocking fd = unsafe_read -- unsafe is ok, it can't block
489 | otherwise = do r <- throwErrnoIfMinus1 loc
490 (unsafe_fdReady (fdFD fd) 0 0 0)
493 else do threadWaitRead (fromIntegral (fdFD fd)); read
495 do_read call = fromIntegral `fmap`
496 throwErrnoIfMinus1RetryMayBlock loc call
497 (threadWaitRead (fromIntegral (fdFD fd)))
498 read = if threaded then safe_read else unsafe_read
499 unsafe_read = do_read (c_read (fdFD fd) (buf `plusPtr` off) len)
500 safe_read = do_read (c_safe_read (fdFD fd) (buf `plusPtr` off) len)
502 -- return: -1 indicates EOF, >=0 is bytes read
503 readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
504 readRawBufferPtrNoBlock loc !fd buf off len
505 | isNonBlocking fd = unsafe_read -- unsafe is ok, it can't block
506 | otherwise = do r <- unsafe_fdReady (fdFD fd) 0 0 0
507 if r /= 0 then safe_read
509 -- XXX see note [nonblock]
511 do_read call = do r <- throwErrnoIfMinus1RetryOnBlock loc call (return (-1))
515 n -> return (fromIntegral n)
516 unsafe_read = do_read (c_read (fdFD fd) (buf `plusPtr` off) len)
517 safe_read = do_read (c_safe_read (fdFD fd) (buf `plusPtr` off) len)
519 writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
520 writeRawBufferPtr loc !fd buf off len
521 | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
522 | otherwise = do r <- unsafe_fdReady (fdFD fd) 1 0 0
525 else do threadWaitWrite (fromIntegral (fdFD fd)); write
527 do_write call = fromIntegral `fmap`
528 throwErrnoIfMinus1RetryMayBlock loc call
529 (threadWaitWrite (fromIntegral (fdFD fd)))
530 write = if threaded then safe_write else unsafe_write
531 unsafe_write = do_write (c_write (fdFD fd) (buf `plusPtr` off) len)
532 safe_write = do_write (c_safe_write (fdFD fd) (buf `plusPtr` off) len)
534 writeRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
535 writeRawBufferPtrNoBlock loc !fd buf off len
536 | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
537 | otherwise = do r <- unsafe_fdReady (fdFD fd) 1 0 0
541 do_write call = do r <- throwErrnoIfMinus1RetryOnBlock loc call (return (-1))
544 n -> return (fromIntegral n)
545 write = if threaded then safe_write else unsafe_write
546 unsafe_write = do_write (c_write (fdFD fd) (buf `plusPtr` off) len)
547 safe_write = do_write (c_safe_write (fdFD fd) (buf `plusPtr` off) len)
549 isNonBlocking :: FD -> Bool
550 isNonBlocking fd = fdIsNonBlocking fd /= 0
552 foreign import ccall unsafe "fdReady"
553 unsafe_fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt
555 #else /* mingw32_HOST_OS.... */
557 readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
558 readRawBufferPtr loc !fd buf off len
559 | threaded = blockingReadRawBufferPtr loc fd buf off len
560 | otherwise = asyncReadRawBufferPtr loc fd buf off len
562 writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
563 writeRawBufferPtr loc !fd buf off len
564 | threaded = blockingWriteRawBufferPtr loc fd buf off len
565 | otherwise = asyncWriteRawBufferPtr loc fd buf off len
567 readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
568 readRawBufferPtrNoBlock = readRawBufferPtr
570 writeRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
571 writeRawBufferPtrNoBlock = writeRawBufferPtr
573 -- Async versions of the read/write primitives, for the non-threaded RTS
575 asyncReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
576 asyncReadRawBufferPtr loc !fd buf off len = do
577 (l, rc) <- asyncRead (fromIntegral (fdFD fd)) (fdIsSocket_ fd)
578 (fromIntegral len) (buf `plusPtr` off)
581 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
582 else return (fromIntegral l)
584 asyncWriteRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
585 asyncWriteRawBufferPtr loc !fd buf off len = do
586 (l, rc) <- asyncWrite (fromIntegral (fdFD fd)) (fdIsSocket_ fd)
587 (fromIntegral len) (buf `plusPtr` off)
590 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
591 else return (fromIntegral l)
593 -- Blocking versions of the read/write primitives, for the threaded RTS
595 blockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
596 blockingReadRawBufferPtr loc fd buf off len
597 = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
599 then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0
600 else c_safe_read (fdFD fd) (buf `plusPtr` off) len
602 blockingWriteRawBufferPtr :: String -> FD -> Ptr Word8-> Int -> CSize -> IO CInt
603 blockingWriteRawBufferPtr loc fd buf off len
604 = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
606 then c_safe_send (fdFD fd) (buf `plusPtr` off) len 0
608 r <- c_safe_write (fdFD fd) (buf `plusPtr` off) len
609 when (r == -1) c_maperrno
611 -- we don't trust write() to give us the correct errno, and
612 -- instead do the errno conversion from GetLastError()
613 -- ourselves. The main reason is that we treat ERROR_NO_DATA
614 -- (pipe is closing) as EPIPE, whereas write() returns EINVAL
615 -- for this case. We need to detect EPIPE correctly, because it
616 -- shouldn't be reported as an error when it happens on stdout.
618 foreign import ccall unsafe "maperrno" -- in Win32Utils.c
621 -- NOTE: "safe" versions of the read/write calls for use by the threaded RTS.
622 -- These calls may block, but that's ok.
624 foreign import stdcall safe "recv"
625 c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
627 foreign import stdcall safe "send"
628 c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
632 foreign import ccall "rtsSupportsBoundThreads" threaded :: Bool
634 -- -----------------------------------------------------------------------------
637 #ifndef mingw32_HOST_OS
638 throwErrnoIfMinus1RetryOnBlock :: String -> IO CSsize -> IO CSsize -> IO CSsize
639 throwErrnoIfMinus1RetryOnBlock loc f on_block =
642 if (res :: CSsize) == -1
646 then throwErrnoIfMinus1RetryOnBlock loc f on_block
647 else if err == eWOULDBLOCK || err == eAGAIN
653 -- -----------------------------------------------------------------------------
656 #ifndef mingw32_HOST_OS
657 foreign import ccall unsafe "lockFile"
658 lockFile :: CInt -> CDev -> CIno -> CInt -> IO CInt
660 foreign import ccall unsafe "unlockFile"
661 unlockFile :: CInt -> IO CInt
664 puts :: String -> IO ()
665 puts s = do _ <- withCStringLen s $ \(p,len) ->
666 c_write 1 (castPtr p) (fromIntegral len)