GHC.Internal.IO.FD

ghc-internal-9.1001.0: Basic libraries

Copyright | (c) The University of Glasgow 1994-2008
License | see libraries/base/LICENSE
Maintainer | libraries@haskell.org
Stability | internal
Portability | non-portable
Safe Haskell | Trustworthy
Language | Haskell2010

GHC.Internal.IO.FD

Description

Raw read/write operations on file descriptors

Synopsis

- data FD = FD {
  - fdFD :: !CInt
  - fdIsNonBlocking :: !Int
  }
- openFileWith :: FilePath -> IOMode -> Bool -> (FD -> IODeviceType -> IO r) -> ((forall x. IO x -> IO x) -> r -> IO s) -> IO s
- openFile :: FilePath -> IOMode -> Bool -> IO (FD, IODeviceType)
- mkFD :: CInt -> IOMode -> Maybe (IODeviceType, CDev, CIno) -> Bool -> Bool -> IO (FD, IODeviceType)
- release :: FD -> IO ()
- setNonBlockingMode :: FD -> Bool -> IO FD
- readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
- readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
- writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
- stdin :: FD
- stdout :: FD
- stderr :: FD

# Documentation

data FD Source #

Constructors

FD |
Fields fdFD :: !CInt fdIsNonBlocking :: !Int On Unix we need to know whether this `FD` has `O_NONBLOCK` set. If it has, then we can use more efficient routines (namely, unsafe FFI) to read/write to it. Otherwise safe FFI is used. `O_NONBLOCK` has no effect on regular files and block devices at the moment, thus this flag should be off for them. While reading from a file cannot block indefinitely (as opposed to reading from a socket or a pipe), it can block the entire runtime for a "brief" moment of time: you cannot read a file from a floppy drive or network share without delay.

#### Instances

Instances details

BufferedIO FD Source # | @since base-4.1.0.0
Instance details Defined in GHC.Internal.IO.FD Methods newBuffer :: FD -> BufferState -> IO (Buffer Word8) Source # fillReadBuffer :: FD -> Buffer Word8 -> IO (Int, Buffer Word8) Source # fillReadBuffer0 :: FD -> Buffer Word8 -> IO (Maybe Int, Buffer Word8) Source # emptyWriteBuffer :: FD -> Buffer Word8 -> IO (Buffer Word8) Source # flushWriteBuffer :: FD -> Buffer Word8 -> IO (Buffer Word8) Source # flushWriteBuffer0 :: FD -> Buffer Word8 -> IO (Int, Buffer Word8) Source #
IODevice FD Source # | @since base-4.1.0.0
Instance details Defined in GHC.Internal.IO.FD Methods ready :: FD -> Bool -> Int -> IO Bool Source # close :: FD -> IO () Source # isTerminal :: FD -> IO Bool Source # isSeekable :: FD -> IO Bool Source # seek :: FD -> SeekMode -> Integer -> IO Integer Source # tell :: FD -> IO Integer Source # getSize :: FD -> IO Integer Source # setSize :: FD -> Integer -> IO () Source # setEcho :: FD -> Bool -> IO () Source # getEcho :: FD -> IO Bool Source # setRaw :: FD -> Bool -> IO () Source # devType :: FD -> IO IODeviceType Source # dup :: FD -> IO FD Source # dup2 :: FD -> FD -> IO FD Source #
RawIO FD Source # | @since base-4.1.0.0
Instance details Defined in GHC.Internal.IO.FD Methods read :: FD -> Ptr Word8 -> Word64 -> Int -> IO Int Source # readNonBlocking :: FD -> Ptr Word8 -> Word64 -> Int -> IO (Maybe Int) Source # write :: FD -> Ptr Word8 -> Word64 -> Int -> IO () Source # writeNonBlocking :: FD -> Ptr Word8 -> Word64 -> Int -> IO Int Source #
Show FD Source # | @since base-4.1.0.0
Instance details Defined in GHC.Internal.IO.FD Methods showsPrec :: Int -> FD -> ShowS Source # show :: FD -> String Source # showList :: [FD] -> ShowS Source #

openFileWith Source #

Arguments

:: FilePath | file to open
-> IOMode | mode in which to open the file
-> Bool | open the file in non-blocking mode? This has no effect on regular files and block devices: they are always opened in blocking mode. See `fdIsNonBlocking` for more discussion.
-> (FD -> IODeviceType -> IO r) | `act1`: An action to perform on the file descriptor with the masking state restored and an exception handler that closes the file on exception.
-> ((forall x. IO x -> IO x) -> r -> IO s) | `act2`: An action to perform with async exceptions masked and no exception handler.
-> IO s |

Open a file and make an `FD` for it. Truncates the file to zero size when the `IOMode` is `WriteMode`.

`openFileWith` takes two actions, `act1` and `act2`, to perform after opening the file.

`act1` is passed a file descriptor and I/O device type for the newly opened file. If an exception occurs in `act1`, then the file will be closed. `act1` must not close the file itself. If it does so and then receives an exception, then the exception handler will attempt to close it again, which is impermissible.

`act2` is performed with asynchronous exceptions masked. It is passed a function to restore the masking state and the result of `act1`. It /must not/ throw an exception (or deliver one via an interruptible operation) without first closing the file or arranging for it to be closed. `act2` may close the file, but is not required to do so. If `act2` leaves the file open, then the file will remain open on return from `openFileWith`.

Code calling `openFileWith` that wishes to install a finalizer to close the file should do so in `act2`. Doing so in `act1` could potentially close the file in the finalizer first and then in the exception handler. See `openFile'` for an example of this use. Regardless, the caller is responsible for ensuring that the file is eventually closed, perhaps using `bracket`.

openFile Source #

Arguments

:: FilePath | file to open
-> IOMode | mode in which to open the file
-> Bool | open the file in non-blocking mode?
-> IO (FD, IODeviceType) |

Open a file and make an `FD` for it. Truncates the file to zero size when the `IOMode` is `WriteMode`. This function is difficult to use without potentially leaking the file descriptor on exception. In particular, it must be used with exceptions masked, which is a bit rude because the thread will be uninterruptible while the file path is being encoded. Use `openFileWith` instead.

mkFD Source #

Arguments

:: CInt |
-> IOMode |
-> Maybe (IODeviceType, CDev, CIno) |
-> Bool | is a socket (on Windows)
-> Bool | is in non-blocking mode on Unix
-> IO (FD, IODeviceType) |

Make a `FD` from an existing file descriptor. Fails if the FD refers to a directory. If the FD refers to a file, `mkFD` locks the file according to the Haskell 2010 single writer/multiple reader locking semantics (this is why we need the `IOMode` argument too).

release :: FD -> IO () Source #

setNonBlockingMode :: FD -> Bool -> IO FD Source #

readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int Source #

readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int Source #

writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt Source #

stdin :: FD Source #

stdout :: FD Source #

stderr :: FD Source #