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`.
144 :: FilePath -- ^ file to open
145 -> IOMode -- ^ mode in which to open the file
146 -> Bool -- ^ open the file in non-blocking mode?
147 -> IO (FD,IODeviceType)
149 openFile filepath iomode non_blocking =
150 withFilePath filepath $ \ f ->
153 oflags1 = case iomode of
154 ReadMode -> read_flags
155 #ifdef mingw32_HOST_OS
156 WriteMode -> write_flags .|. o_TRUNC
158 WriteMode -> write_flags
160 ReadWriteMode -> rw_flags
161 AppendMode -> append_flags
163 #ifdef mingw32_HOST_OS
164 binary_flags = o_BINARY
169 oflags2 = oflags1 .|. binary_flags
171 oflags | non_blocking = oflags2 .|. nonblock_flags
172 | otherwise = oflags2
175 -- the old implementation had a complicated series of three opens,
176 -- which is perhaps because we have to be careful not to open
177 -- directories. However, the man pages I've read say that open()
178 -- always returns EISDIR if the file is a directory and was opened
179 -- for writing, so I think we're ok with a single open() here...
180 fd <- throwErrnoIfMinus1Retry "openFile"
181 (if non_blocking then c_open f oflags 0o666
182 else c_safe_open f oflags 0o666)
184 (fD,fd_type) <- mkFD fd iomode Nothing{-no stat-}
185 False{-not a socket-}
187 `catchAny` \e -> do _ <- c_close fd
190 #ifndef mingw32_HOST_OS
191 -- we want to truncate() if this is an open in WriteMode, but only
192 -- if the target is a RegularFile. ftruncate() fails on special files
194 if iomode == WriteMode && fd_type == RegularFile
201 std_flags, output_flags, read_flags, write_flags, rw_flags,
202 append_flags, nonblock_flags :: CInt
204 output_flags = std_flags .|. o_CREAT
205 read_flags = std_flags .|. o_RDONLY
206 write_flags = output_flags .|. o_WRONLY
207 rw_flags = output_flags .|. o_RDWR
208 append_flags = write_flags .|. o_APPEND
209 nonblock_flags = o_NONBLOCK
212 -- | Make a 'FD' from an existing file descriptor. Fails if the FD
213 -- refers to a directory. If the FD refers to a file, `mkFD` locks
214 -- the file according to the Haskell 98 single writer/multiple reader
215 -- locking semantics (this is why we need the `IOMode` argument too).
218 -> Maybe (IODeviceType, CDev, CIno)
219 -- the results of fdStat if we already know them, or we want
220 -- to prevent fdToHandle_stat from doing its own stat.
221 -- These are used for:
222 -- - we fail if the FD refers to a directory
223 -- - if the FD refers to a file, we lock it using (cdev,cino)
224 -> Bool -- ^ is a socket (on Windows)
225 -> Bool -- ^ is in non-blocking mode on Unix
226 -> IO (FD,IODeviceType)
228 mkFD fd iomode mb_stat is_socket is_nonblock = do
230 let _ = (is_socket, is_nonblock) -- warning suppression
235 Just stat -> return stat
237 let write = case iomode of
241 #ifdef mingw32_HOST_OS
242 _ <- setmode fd True -- unconditionally set binary mode
243 let _ = (dev,ino,write) -- warning suppression
248 ioException (IOError Nothing InappropriateType "openFile"
249 "is a directory" Nothing Nothing)
251 #ifndef mingw32_HOST_OS
252 -- regular files need to be locked
254 -- On Windows we use explicit exclusion via sopen() to implement
255 -- this locking (see __hscore_open()); on Unix we have to
256 -- implment it in the RTS.
257 r <- lockFile fd dev ino (fromBool write)
259 ioException (IOError Nothing ResourceBusy "openFile"
260 "file is locked" Nothing Nothing)
263 _other_type -> return ()
265 return (FD{ fdFD = fd,
266 #ifndef mingw32_HOST_OS
267 fdIsNonBlocking = fromEnum is_nonblock
269 fdIsSocket_ = fromEnum is_socket
274 #ifdef mingw32_HOST_OS
275 foreign import ccall unsafe "__hscore_setmode"
276 setmode :: CInt -> Bool -> IO CInt
279 -- -----------------------------------------------------------------------------
280 -- Standard file descriptors
283 stdFD fd = FD { fdFD = fd,
284 #ifdef mingw32_HOST_OS
288 -- We don't set non-blocking mode on standard handles, because it may
289 -- confuse other applications attached to the same TTY/pipe
290 -- see Note [nonblock]
294 stdin, stdout, stderr :: FD
299 -- -----------------------------------------------------------------------------
300 -- Operations on file descriptors
304 #ifndef mingw32_HOST_OS
305 (flip finally) (release fd) $
307 do let closer realFd =
308 throwErrnoIfMinus1Retry_ "GHC.IO.FD.close" $
309 #ifdef mingw32_HOST_OS
310 if fdIsSocket fd then
311 c_closesocket (fromIntegral realFd)
314 c_close (fromIntegral realFd)
315 closeFdWith closer (fromIntegral (fdFD fd))
317 release :: FD -> IO ()
318 #ifdef mingw32_HOST_OS
319 release _ = return ()
321 release fd = do _ <- unlockFile (fdFD fd)
325 #ifdef mingw32_HOST_OS
326 foreign import stdcall unsafe "HsBase.h closesocket"
327 c_closesocket :: CInt -> IO CInt
330 isSeekable :: FD -> IO Bool
333 return (t == RegularFile || t == RawDevice)
335 seek :: FD -> SeekMode -> Integer -> IO ()
336 seek fd mode off = do
337 throwErrnoIfMinus1Retry_ "seek" $
338 c_lseek (fdFD fd) (fromIntegral off) seektype
341 seektype = case mode of
342 AbsoluteSeek -> sEEK_SET
343 RelativeSeek -> sEEK_CUR
344 SeekFromEnd -> sEEK_END
346 tell :: FD -> IO Integer
349 (throwErrnoIfMinus1Retry "hGetPosn" $
350 c_lseek (fdFD fd) 0 sEEK_CUR)
352 getSize :: FD -> IO Integer
353 getSize fd = fdFileSize (fdFD fd)
355 setSize :: FD -> Integer -> IO ()
357 throwErrnoIf_ (/=0) "GHC.IO.FD.setSize" $
358 c_ftruncate (fdFD fd) (fromIntegral size)
360 devType :: FD -> IO IODeviceType
361 devType fd = do (ty,_,_) <- fdStat (fdFD fd); return ty
365 newfd <- throwErrnoIfMinus1 "GHC.IO.FD.dup" $ c_dup (fdFD fd)
366 return fd{ fdFD = newfd }
368 dup2 :: FD -> FD -> IO FD
370 -- Windows' dup2 does not return the new descriptor, unlike Unix
371 throwErrnoIfMinus1_ "GHC.IO.FD.dup2" $
372 c_dup2 (fdFD fd) (fdFD fdto)
373 return fd{ fdFD = fdFD fdto } -- original FD, with the new fdFD
375 setNonBlockingMode :: FD -> Bool -> IO FD
376 setNonBlockingMode fd set = do
377 setNonBlockingFD (fdFD fd) set
378 #if defined(mingw32_HOST_OS)
381 return fd{ fdIsNonBlocking = fromEnum set }
384 ready :: FD -> Bool -> Int -> IO Bool
385 ready fd write msecs = do
386 r <- throwErrnoIfMinus1Retry "GHC.IO.FD.ready" $
387 fdReady (fdFD fd) (fromIntegral $ fromEnum $ write)
389 #if defined(mingw32_HOST_OS)
390 (fromIntegral $ fromEnum $ fdIsSocket fd)
394 return (toEnum (fromIntegral r))
396 foreign import ccall safe "fdReady"
397 fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt
399 -- ---------------------------------------------------------------------------
400 -- Terminal-related stuff
402 isTerminal :: FD -> IO Bool
404 #if defined(mingw32_HOST_OS)
405 is_console (fdFD fd) >>= return.toBool
407 c_isatty (fdFD fd) >>= return.toBool
410 setEcho :: FD -> Bool -> IO ()
411 setEcho fd on = System.Posix.Internals.setEcho (fdFD fd) on
413 getEcho :: FD -> IO Bool
414 getEcho fd = System.Posix.Internals.getEcho (fdFD fd)
416 setRaw :: FD -> Bool -> IO ()
417 setRaw fd raw = System.Posix.Internals.setCooked (fdFD fd) (not raw)
419 -- -----------------------------------------------------------------------------
420 -- Reading and Writing
422 fdRead :: FD -> Ptr Word8 -> Int -> IO Int
424 = do { r <- readRawBufferPtr "GHC.IO.FD.fdRead" fd ptr 0 (fromIntegral bytes)
425 ; return (fromIntegral r) }
427 fdReadNonBlocking :: FD -> Ptr Word8 -> Int -> IO (Maybe Int)
428 fdReadNonBlocking fd ptr bytes = do
429 r <- readRawBufferPtrNoBlock "GHC.IO.FD.fdReadNonBlocking" fd ptr
430 0 (fromIntegral bytes)
431 case fromIntegral r of
432 (-1) -> return (Nothing)
436 fdWrite :: FD -> Ptr Word8 -> Int -> IO ()
437 fdWrite fd ptr bytes = do
438 res <- writeRawBufferPtr "GHC.IO.FD.fdWrite" fd ptr 0 (fromIntegral bytes)
439 let res' = fromIntegral res
441 then fdWrite fd (ptr `plusPtr` res') (bytes - res')
444 -- XXX ToDo: this isn't non-blocking
445 fdWriteNonBlocking :: FD -> Ptr Word8 -> Int -> IO Int
446 fdWriteNonBlocking fd ptr bytes = do
447 res <- writeRawBufferPtrNoBlock "GHC.IO.FD.fdWriteNonBlocking" fd ptr 0
449 return (fromIntegral res)
451 -- -----------------------------------------------------------------------------
454 -- Low level routines for reading/writing to (raw)buffers:
456 #ifndef mingw32_HOST_OS
461 Unix has broken semantics when it comes to non-blocking I/O: you can
462 set the O_NONBLOCK flag on an FD, but it applies to the all other FDs
463 attached to the same underlying file, pipe or TTY; there's no way to
464 have private non-blocking behaviour for an FD. See bug #724.
466 We fix this by only setting O_NONBLOCK on FDs that we create; FDs that
467 come from external sources or are exposed externally are left in
468 blocking mode. This solution has some problems though. We can't
469 completely simulate a non-blocking read without O_NONBLOCK: several
470 cases are wrong here. The cases that are wrong:
472 * reading/writing to a blocking FD in non-threaded mode.
473 In threaded mode, we just make a safe call to read().
474 In non-threaded mode we call select() before attempting to read,
475 but that leaves a small race window where the data can be read
476 from the file descriptor before we issue our blocking read().
477 * readRawBufferNoBlock for a blocking FD
481 In the threaded RTS we could just make safe calls to read()/write()
482 for file descriptors in blocking mode without worrying about blocking
483 other threads, but the problem with this is that the thread will be
484 uninterruptible while it is blocked in the foreign call. See #2363.
485 So now we always call fdReady() before reading, and if fdReady
486 indicates that there's no data, we call threadWaitRead.
490 readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
491 readRawBufferPtr loc !fd buf off len
492 | isNonBlocking fd = unsafe_read -- unsafe is ok, it can't block
493 | otherwise = do r <- throwErrnoIfMinus1 loc
494 (unsafe_fdReady (fdFD fd) 0 0 0)
497 else do threadWaitRead (fromIntegral (fdFD fd)); read
499 do_read call = fromIntegral `fmap`
500 throwErrnoIfMinus1RetryMayBlock loc call
501 (threadWaitRead (fromIntegral (fdFD fd)))
502 read = if threaded then safe_read else unsafe_read
503 unsafe_read = do_read (c_read (fdFD fd) (buf `plusPtr` off) len)
504 safe_read = do_read (c_safe_read (fdFD fd) (buf `plusPtr` off) len)
506 -- return: -1 indicates EOF, >=0 is bytes read
507 readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
508 readRawBufferPtrNoBlock loc !fd buf off len
509 | isNonBlocking fd = unsafe_read -- unsafe is ok, it can't block
510 | otherwise = do r <- unsafe_fdReady (fdFD fd) 0 0 0
511 if r /= 0 then safe_read
513 -- XXX see note [nonblock]
515 do_read call = do r <- throwErrnoIfMinus1RetryOnBlock loc call (return (-1))
519 n -> return (fromIntegral n)
520 unsafe_read = do_read (c_read (fdFD fd) (buf `plusPtr` off) len)
521 safe_read = do_read (c_safe_read (fdFD fd) (buf `plusPtr` off) len)
523 writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
524 writeRawBufferPtr loc !fd buf off len
525 | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
526 | otherwise = do r <- unsafe_fdReady (fdFD fd) 1 0 0
529 else do threadWaitWrite (fromIntegral (fdFD fd)); write
531 do_write call = fromIntegral `fmap`
532 throwErrnoIfMinus1RetryMayBlock loc call
533 (threadWaitWrite (fromIntegral (fdFD fd)))
534 write = if threaded then safe_write else unsafe_write
535 unsafe_write = do_write (c_write (fdFD fd) (buf `plusPtr` off) len)
536 safe_write = do_write (c_safe_write (fdFD fd) (buf `plusPtr` off) len)
538 writeRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
539 writeRawBufferPtrNoBlock loc !fd buf off len
540 | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
541 | otherwise = do r <- unsafe_fdReady (fdFD fd) 1 0 0
545 do_write call = do r <- throwErrnoIfMinus1RetryOnBlock loc call (return (-1))
548 n -> return (fromIntegral n)
549 write = if threaded then safe_write else unsafe_write
550 unsafe_write = do_write (c_write (fdFD fd) (buf `plusPtr` off) len)
551 safe_write = do_write (c_safe_write (fdFD fd) (buf `plusPtr` off) len)
553 isNonBlocking :: FD -> Bool
554 isNonBlocking fd = fdIsNonBlocking fd /= 0
556 foreign import ccall unsafe "fdReady"
557 unsafe_fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt
559 #else /* mingw32_HOST_OS.... */
561 readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
562 readRawBufferPtr loc !fd buf off len
563 | threaded = blockingReadRawBufferPtr loc fd buf off len
564 | otherwise = asyncReadRawBufferPtr loc fd buf off len
566 writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
567 writeRawBufferPtr loc !fd buf off len
568 | threaded = blockingWriteRawBufferPtr loc fd buf off len
569 | otherwise = asyncWriteRawBufferPtr loc fd buf off len
571 readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
572 readRawBufferPtrNoBlock = readRawBufferPtr
574 writeRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
575 writeRawBufferPtrNoBlock = writeRawBufferPtr
577 -- Async versions of the read/write primitives, for the non-threaded RTS
579 asyncReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
580 asyncReadRawBufferPtr loc !fd buf off len = do
581 (l, rc) <- asyncRead (fromIntegral (fdFD fd)) (fdIsSocket_ fd)
582 (fromIntegral len) (buf `plusPtr` off)
585 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
586 else return (fromIntegral l)
588 asyncWriteRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
589 asyncWriteRawBufferPtr loc !fd buf off len = do
590 (l, rc) <- asyncWrite (fromIntegral (fdFD fd)) (fdIsSocket_ fd)
591 (fromIntegral len) (buf `plusPtr` off)
594 ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
595 else return (fromIntegral l)
597 -- Blocking versions of the read/write primitives, for the threaded RTS
599 blockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
600 blockingReadRawBufferPtr loc fd buf off len
601 = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
603 then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0
604 else c_safe_read (fdFD fd) (buf `plusPtr` off) len
606 blockingWriteRawBufferPtr :: String -> FD -> Ptr Word8-> Int -> CSize -> IO CInt
607 blockingWriteRawBufferPtr loc fd buf off len
608 = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
610 then c_safe_send (fdFD fd) (buf `plusPtr` off) len 0
612 r <- c_safe_write (fdFD fd) (buf `plusPtr` off) len
613 when (r == -1) c_maperrno
615 -- we don't trust write() to give us the correct errno, and
616 -- instead do the errno conversion from GetLastError()
617 -- ourselves. The main reason is that we treat ERROR_NO_DATA
618 -- (pipe is closing) as EPIPE, whereas write() returns EINVAL
619 -- for this case. We need to detect EPIPE correctly, because it
620 -- shouldn't be reported as an error when it happens on stdout.
622 foreign import ccall unsafe "maperrno" -- in Win32Utils.c
625 -- NOTE: "safe" versions of the read/write calls for use by the threaded RTS.
626 -- These calls may block, but that's ok.
628 foreign import stdcall safe "recv"
629 c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
631 foreign import stdcall safe "send"
632 c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
636 foreign import ccall "rtsSupportsBoundThreads" threaded :: Bool
638 -- -----------------------------------------------------------------------------
641 #ifndef mingw32_HOST_OS
642 throwErrnoIfMinus1RetryOnBlock :: String -> IO CSsize -> IO CSsize -> IO CSsize
643 throwErrnoIfMinus1RetryOnBlock loc f on_block =
646 if (res :: CSsize) == -1
650 then throwErrnoIfMinus1RetryOnBlock loc f on_block
651 else if err == eWOULDBLOCK || err == eAGAIN
657 -- -----------------------------------------------------------------------------
660 #ifndef mingw32_HOST_OS
661 foreign import ccall unsafe "lockFile"
662 lockFile :: CInt -> CDev -> CIno -> CInt -> IO CInt
664 foreign import ccall unsafe "unlockFile"
665 unlockFile :: CInt -> IO CInt
668 puts :: String -> IO ()
669 puts s = do _ <- withCStringLen s $ \(p,len) ->
670 c_write 1 (castPtr p) (fromIntegral len)