summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/IO/Handle.hs
Commit message (Collapse)AuthorAgeFilesLines
* Expand documentation of hIsTerminalDeviceBodigrim2022-05-281-1/+8
|
* Make openFile exception safeDavid Feuer2021-02-221-20/+6
| | | | | | | | | | | | | | | | | | | * `openFile` could sometimes leak file descriptors if it received an asynchronous exception (#19114, #19115). Fix this on POSIX. * `openFile` and more importantly `openFileBlocking` could not be interrupted effectively during the `open` system call (#17912). Fix this on POSIX. * Implement `readFile'` using `withFile` to ensure the file is closed promptly on exception. * Avoid `bracket` in `withFile`, reducing the duration of masking. Closes #19130. Addresses #17912, #19114, and #19115 on POSIX systems, but not on Windows.
* Remove redundant "do", "return" and language extensions from baseHécate2020-09-231-8/+8
|
* winio: clarify comment on cooked mode.Tamar Christina2020-07-151-1/+2
|
* winio: Rename SmartHandles to StdHandlesAndreas Klebinger2020-07-151-1/+1
|
* winio: Detect running IO Backend via peeking at RtsConfigAndreas Klebinger2020-07-151-2/+1
|
* winio: Fix offset set by bufReadEmpty.Andreas Klebinger2020-07-151-3/+4
| | | | | | | bufReadEmpty returns the bytes read *including* content that was already buffered, But for calculating the offset we only care about the number of bytes read into the new buffer.
* winio: Refactor Buffer structures to be able to track async operationsTamar Christina2020-07-151-11/+33
|
* base: add strict IO functions: readFile', getContents', hGetContents'Lysxia2020-03-161-1/+1
|
* Avoid race condition in hDuplicateToMoritz Kiefer2019-12-191-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In our codebase we have some code along the lines of ``` newStdout <- hDuplicate stdout stderr `hDuplicateTo` stdout ``` to avoid stray `putStrLn`s from corrupting a protocol (LSP) that is run over stdout. On CI we have seen a bunch of issues where `dup2` returned `EBUSY` so this fails with `ResourceExhausted` in Haskell. I’ve spent some time looking at the docs for `dup2` and the code in `base` and afaict the following race condition is being triggered here: 1. The user calls `hDuplicateTo stderr stdout`. 2. `hDuplicateTo` calls `hClose_help stdout_`, this closes the file handle for stdout. 3. The file handle for stdout is now free, so another thread allocating a file might get stdout. 4. If `dup2` is called while `stdout` (now pointing to something else) is half-open, it returns EBUSY. I think there might actually be an even worse case where `dup2` is run after FD 1 is fully open again. In that case, you will end up not just redirecting the original stdout to stderr but also the whatever resulted in that file handle being allocated. As far as I can tell, `dup2` takes care of closing the file handle itself so there is no reason to do this in `hDuplicateTo`. So this PR replaces the call to `hClose_help` by the only part of `hClose_help` that we actually care about, namely, `flushWriteBuffer`. I tested this on our codebase fairly extensively and haven’t been able to reproduce the issue with this patch.
* Implement -Wredundant-record-wildcards and -Wunused-record-wildcardsMatthew Pickering2019-02-141-2/+2
| | | | | | | | | -Wredundant-record-wildcards warns when a .. pattern binds no variables. -Wunused-record-wildcards warns when none of the variables bound by a .. pattern are used. These flags are enabled by `-Wall`.
* Fix ambiguous/out-of-scope Haddock identifiersAlec Theriault2018-08-211-21/+23
| | | | | | | | | | | | | | | | | This drastically cuts down on the number of Haddock warnings when making docs for `base`. Plus this means more actual links end up in the docs! Also fixed other small mostly markup issues in the documentation along the way. This is a docs-only change. Reviewers: hvr, bgamari, thomie Reviewed By: thomie Subscribers: thomie, rwbarton, carter Differential Revision: https://phabricator.haskell.org/D5055
* Prefer #if defined to #ifdefBen Gamari2017-04-281-1/+1
| | | | Our new CPP linter enforces this.
* Add support for concurrent package db access and updatesAndrzej Rybczak2017-02-261-1/+14
| | | | | | | | | | Trac issues: #13194 Reviewers: austin, hvr, erikd, bgamari, dfeuer, duncan Subscribers: DemiMarie, dfeuer, thomie Differential Revision: https://phabricator.haskell.org/D3090
* Add @since annotations to base instancesSeraphime Kirkovski2016-06-061-0/+2
| | | | | | | | | | | | | | | | | | Add @since annotations to instances in `base`. Test Plan: * ./validate # some commets shouldn't break the build * review the annotations for absurdities. Reviewers: ekmett, goldfire, RyanGlScott, austin, hvr, bgamari Reviewed By: RyanGlScott, hvr, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2277 GHC Trac Issues: #11767
* Allow CallStacks to be frozenEric Seidel2015-12-231-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This introduces "freezing," an operation which prevents further locations from being appended to a CallStack. Library authors may want to prevent CallStacks from exposing implementation details, as a matter of hygiene. For example, in ``` head [] = error "head: empty list" ghci> head [] *** Exception: head: empty list CallStack (from implicit params): error, called at ... ``` including the call-site of `error` in `head` is not strictly necessary as the error message already specifies clearly where the error came from. So we add a function `freezeCallStack` that wraps an existing CallStack, preventing further call-sites from being pushed onto it. In other words, ``` pushCallStack callSite (freezeCallStack callStack) = freezeCallStack callStack ``` Now we can define `head` to not produce a CallStack at all ``` head [] = let ?callStack = freezeCallStack emptyCallStack in error "head: empty list" ghci> head [] *** Exception: head: empty list CallStack (from implicit params): error, called at ... ``` --- 1. We add the `freezeCallStack` and `emptyCallStack` and update the definition of `CallStack` to support this functionality. 2. We add `errorWithoutStackTrace`, a variant of `error` that does not produce a stack trace, using this feature. I think this is a sensible wrapper function to provide in case users want it. 3. We replace uses of `error` in base with `errorWithoutStackTrace`. The rationale is that base does not export any functions that use CallStacks (except for `error` and `undefined`) so there's no way for the stack traces (from Implicit CallStacks) to include user-defined functions. They'll only contain the call to `error` itself. As base already has a good habit of providing useful error messages that name the triggering function, the stack trace really just adds noise to the error. (I don't have a strong opinion on whether we should include this third commit, but the change was very mechanical so I thought I'd include it anyway in case there's interest) 4. Updates tests in `array` and `stm` submodules Test Plan: ./validate, new test is T11049 Reviewers: simonpj, nomeata, goldfire, austin, hvr, bgamari Reviewed By: simonpj Subscribers: thomie Projects: #ghc Differential Revision: https://phabricator.haskell.org/D1628 GHC Trac Issues: #11049
* IO Handles: update comments [skip ci]Thomas Miedema2015-12-171-1/+1
| | | | | | | * hSetEcho, hGetEcho and hIsTerminalDevice are part of the Haskell2010 report (but not Haskell98) * there are great `Note`s in GHC.IO.Handle.Types. Link to them.
* Start using `-W` instead of `-f(no-)warn` in some placesHerbert Valerio Riedel2015-12-161-1/+1
| | | | | | | | | | | | | | | | | | This replaces some occurences of `-f(no-)warn` with the new `-W`-aliases introduced via 2206fa8cdb120932 / #11218, in cases which are guaranteed to be invoked with recent enough GHC (i.e. the stage1+ GHC). After this commit, mostly the compiler and the testsuite remain using `-f(wo-)warn...` because the compiler needs to be bootstrappable with older GHCs, while for the testsuite it's convenient to be able to quickly compare the behavior to older GHCs (which may not support the new flags yet). The compiler-part can be updated to use the new flags once GHC 8.3 development starts. Reviewed By: quchen Differential Revision: https://phabricator.haskell.org/D1637
* Mention "handle is semi-closed" in error messagesThomas Miedema2015-12-151-5/+5
| | | | | | | | | | | Semi-closedness is mentioned in the Haskell report, so lets not hide it from users. Reviewers: austin, hvr, bgamari Reviewed By: bgamari Differential Revision: https://phabricator.haskell.org/D1624
* `M-x delete-trailing-whitespace` & `M-x untabify`Herbert Valerio Riedel2014-09-241-53/+53
| | | | ...several modules in `base` recently touched by me
* Move `mapM` and `sequence` to GHC.Base and break import-cyclesHerbert Valerio Riedel2014-09-211-1/+0
| | | | | | | | | | This simplifies the import graph and more importantly removes import cycles that arise due to `Control.Monad` & `Data.List` importing `Data.Traversable` (preparation for #9586) Reviewed By: ekmett, austin Differential Revision: https://phabricator.haskell.org/D234
* Move `when` to GHC.BaseHerbert Valerio Riedel2014-09-181-1/+1
| | | | | | | | | This allows several modules to avoid importing Control.Monad and thus break import cycles that manifest themselves when implementing #9586 Reviewed By: austin, ekmett Differential Revision: https://phabricator.haskell.org/D222
* Make the fileSystemEncoding/localeEncoding/foreignEncoding mutableMax Bolingbroke2011-11-181-3/+3
|
* Update base for latest Safe Haskell.David Terei2011-10-251-0/+1
|
* SafeHaskell: Added SafeHaskell to baseDavid Terei2011-06-181-0/+1
|
* Add System.IO.char8, the encoding used by openBinaryFile,Simon Marlow2011-05-241-1/+1
| | | | | | and correct the documentation for hSetBinaryMode which claimed that it was using the latin1 encoding when in fact it was using an unchecked modulo-256 version of it.
* Use explicit language extensions & remove extension fields from base.cabalsimonpj@microsoft.com2011-01-281-1/+5
| | | | | | | | | | Add explicit {-# LANGUAGE xxx #-} pragmas to each module, that say what extensions that module uses. This makes it clearer where different extensions are used in the (large, variagated) base package. Now base.cabal doesn't need any extensions field Thanks to Bas van Dijk for doing all the work.
* fix a discarded exception in hCloseSimon Marlow2010-12-011-6/+3
|
* fix hTell behaviour with Unicode HandlesSimon Marlow2010-11-251-5/+8
|
* Encode immediately in hPutStr and hPutCharSimon Marlow2010-11-251-25/+5
| | | | | | | | | | This means that decoding errors will be detected accurately, and can be caught and handled. Overall the implementation is simpler this way too. It does impose a performance hit on small hPutStrs, although larger hPutStrs seem to be unaffected. To compensate somewhat, I optimised hPutStrLn.
* use LANGUAGE instead of OPTIONS_GHCSimon Marlow2010-11-241-1/+2
|
* doc formatting fixSimon Marlow2010-07-141-1/+2
|
* Fix a few places where we forgot to close the text codecs (#4029)Simon Marlow2010-07-021-0/+2
| | | | | Each time you invoke :load in GHCi it resets the CAFs, including stdin/stdout/stderr, and each of these was allocating a new iconv_t.
* doc updates in System.IOSimon Marlow2010-06-291-0/+11
|
* hSetEncoding: change the encoding on both read and write sides (#4066)Simon Marlow2010-05-141-3/+2
|
* hIsEOF: don't do any decoding (#3808)Simon Marlow2010-01-121-7/+17
|
* Fix #3534: No need to flush the byte buffer when setting binary modeSimon Marlow2009-09-231-1/+1
|
* warning fix: -fno-implicit-prelude -> -XNoImplicitPreludeSimon Marlow2009-07-151-2/+1
|
* Add hGetEncoding :: Handle -> IO (Maybe TextEncoding)Simon Marlow2009-07-151-2/+19
| | | | as suggested during the discussion on the libraries list
* Export Unicode and newline functionality from System.IO; update Haddock docsSimon Marlow2009-07-131-2/+4
|
* Fix some "warn-unused-do-bind" warnings where we want to ignore the valueIan Lynagh2009-07-101-2/+2
|
* add hFlushAll, flushes both read and write buffersSimon Marlow2009-06-231-1/+21
|
* Save and restore the codec state when re-decodingSimon Marlow2009-06-141-4/+12
| | | | | | | | | | | | | We previously had an ugly hack to check for a BOM when re-decoding some binary data in flushCharBuffer. The hack was there essentially because codecs like UTF-16 have a state, and we had not restored it. This patch gives codecs an explicit state, and implemented saving/restoring of the state as necessary. Hence, the hack in flushCharBuffer is replaced by a more general mechanism that works for any codec with state. Unfortunately, iconv doesn't give us a way to save and restore the state, so this is currently only implemented for the built-in codecs.
* Fix #3128: file descriptor leak when hClose failsSimon Marlow2009-06-161-6/+8
|
* Rewrite of the IO library, including Unicode supportSimon Marlow2009-06-121-0/+686
Highlights: * Unicode support for Handle I/O: ** Automatic encoding and decoding using a per-Handle encoding. ** The encoding defaults to the locale encoding (only on Unix so far, perhaps Windows later). ** Built-in UTF-8, UTF-16 (BE/LE), and UTF-32 (BE/LE) codecs. ** iconv-based codec for other encodings on Unix * Modularity: the low-level IO interface is exposed as a type class (GHC.IO.IODevice) so you can build your own low-level IO providers and make Handles from them. * Newline translation: instead of being Windows-specific wired-in magic, the translation from \r\n -> \n and back again is available on all platforms and is configurable for reading/writing independently. Unicode-aware Handles ~~~~~~~~~~~~~~~~~~~~~ This is a significant restructuring of the Handle implementation with the primary goal of supporting Unicode character encodings. The only change to the existing behaviour is that by default, text IO is done in the prevailing locale encoding of the system (except on Windows [1]). Handles created by openBinaryFile use the Latin-1 encoding, as do Handles placed in binary mode using hSetBinaryMode. We provide a way to change the encoding for an existing Handle: GHC.IO.Handle.hSetEncoding :: Handle -> TextEncoding -> IO () and various encodings (from GHC.IO.Encoding): latin1, utf8, utf16, utf16le, utf16be, utf32, utf32le, utf32be, localeEncoding, and a way to lookup other encodings: GHC.IO.Encoding.mkTextEncoding :: String -> IO TextEncoding (it's system-dependent whether the requested encoding will be available). We may want to export these from somewhere more permanent; that's a topic for a future library proposal. Thanks to suggestions from Duncan Coutts, it's possible to call hSetEncoding even on buffered read Handles, and the right thing happens. So we can read from text streams that include multiple encodings, such as an HTTP response or email message, without having to turn buffering off (though there is a penalty for switching encodings on a buffered Handle, as the IO system has to do some re-decoding to figure out where it should start reading from again). If there is a decoding error, it is reported when an attempt is made to read the offending character from the Handle, as you would expect. Performance varies. For "hGetContents >>= putStr" I found the new library was faster on my x86_64 machine, but slower on an x86. On the whole I'd expect things to be a bit slower due to the extra decoding/encoding, but probabaly not noticeably. If performance is critical for your app, then you should be using bytestring and text anyway. [1] Note: locale encoding is not currently implemented on Windows due to the built-in Win32 APIs for encoding/decoding not being sufficient for our purposes. Ask me for details. Offers of help gratefully accepted. Newline Translation ~~~~~~~~~~~~~~~~~~~ In the old IO library, text-mode Handles on Windows had automatic translation from \r\n -> \n on input, and the opposite on output. It was implemented using the underlying CRT functions, which meant that there were certain odd restrictions, such as read/write text handles needing to be unbuffered, and seeking not working at all on text Handles. In the rewrite, newline translation is now implemented in the upper layers, as it needs to be since we have to perform Unicode decoding before newline translation. This means that it is now available on all platforms, which can be quite handy for writing portable code. For now, I have left the behaviour as it was, namely \r\n -> \n on Windows, and no translation on Unix. However, another reasonable default (similar to what Python does) would be to do \r\n -> \n on input, and convert to the platform-native representation (either \r\n or \n) on output. This is called universalNewlineMode (below). The API is as follows. (available from GHC.IO.Handle for now, again this is something we will probably want to try to get into System.IO at some point): -- | The representation of a newline in the external file or stream. data Newline = LF -- ^ "\n" | CRLF -- ^ "\r\n" deriving Eq -- | Specifies the translation, if any, of newline characters between -- internal Strings and the external file or stream. Haskell Strings -- are assumed to represent newlines with the '\n' character; the -- newline mode specifies how to translate '\n' on output, and what to -- translate into '\n' on input. data NewlineMode = NewlineMode { inputNL :: Newline, -- ^ the representation of newlines on input outputNL :: Newline -- ^ the representation of newlines on output } deriving Eq -- | The native newline representation for the current platform nativeNewline :: Newline -- | Map "\r\n" into "\n" on input, and "\n" to the native newline -- represetnation on output. This mode can be used on any platform, and -- works with text files using any newline convention. The downside is -- that @readFile a >>= writeFile b@ might yield a different file. universalNewlineMode :: NewlineMode universalNewlineMode = NewlineMode { inputNL = CRLF, outputNL = nativeNewline } -- | Use the native newline representation on both input and output nativeNewlineMode :: NewlineMode nativeNewlineMode = NewlineMode { inputNL = nativeNewline, outputNL = nativeNewline } -- | Do no newline translation at all. noNewlineTranslation :: NewlineMode noNewlineTranslation = NewlineMode { inputNL = LF, outputNL = LF } -- | Change the newline translation mode on the Handle. hSetNewlineMode :: Handle -> NewlineMode -> IO () IO Devices ~~~~~~~~~~ The major change here is that the implementation of the Handle operations is separated from the underlying IO device, using type classes. File descriptors are just one IO provider; I have also implemented memory-mapped files (good for random-access read/write) and a Handle that pipes output to a Chan (useful for testing code that writes to a Handle). New kinds of Handle can be implemented outside the base package, for instance someone could write bytestringToHandle. A Handle is made using mkFileHandle: -- | makes a new 'Handle' mkFileHandle :: (IODevice dev, BufferedIO dev, Typeable dev) => dev -- ^ the underlying IO device, which must support -- 'IODevice', 'BufferedIO' and 'Typeable' -> FilePath -- ^ a string describing the 'Handle', e.g. the file -- path for a file. Used in error messages. -> IOMode -- ^ The mode in which the 'Handle' is to be used -> Maybe TextEncoding -- ^ text encoding to use, if any -> NewlineMode -- ^ newline translation mode -> IO Handle This also means that someone can write a completely new IO implementation on Windows based on native Win32 HANDLEs, and distribute it as a separate package (I really hope somebody does this!). This restructuring isn't as radical as previous designs. I haven't made any attempt to make a separate binary I/O layer, for example (although hGetBuf/hPutBuf do bypass the text encoding and newline translation). The main goal here was to get Unicode support in, and to allow others to experiment with making new kinds of Handle. We could split up the layers further later. API changes and Module structure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB. GHC.IOBase and GHC.Handle are now DEPRECATED (they are still present, but are just re-exporting things from other modules now). For 6.12 we'll want to bump base to version 5 and add a base4-compat. For now I'm using #if __GLASGOW_HASKEL__ >= 611 to avoid deprecated warnings. I split modules into smaller parts in many places. For example, we now have GHC.IORef, GHC.MVar and GHC.IOArray containing the implementations of IORef, MVar and IOArray respectively. This was necessary for untangling dependencies, but it also makes things easier to follow. The new module structurue for the IO-relatied parts of the base package is: GHC.IO Implementation of the IO monad; unsafe*; throw/catch GHC.IO.IOMode The IOMode type GHC.IO.Buffer Buffers and operations on them GHC.IO.Device The IODevice and RawIO classes. GHC.IO.BufferedIO The BufferedIO class. GHC.IO.FD The FD type, with instances of IODevice, RawIO and BufferedIO. GHC.IO.Exception IO-related Exceptions GHC.IO.Encoding The TextEncoding type; built-in TextEncodings; mkTextEncoding GHC.IO.Encoding.Types GHC.IO.Encoding.Iconv GHC.IO.Encoding.Latin1 GHC.IO.Encoding.UTF8 GHC.IO.Encoding.UTF16 GHC.IO.Encoding.UTF32 Implementation internals for GHC.IO.Encoding GHC.IO.Handle The main API for GHC's Handle implementation, provides all the Handle operations + mkFileHandle + hSetEncoding. GHC.IO.Handle.Types GHC.IO.Handle.Internals GHC.IO.Handle.Text Implementation of Handles and operations. GHC.IO.Handle.FD Parts of the Handle API implemented by file-descriptors: openFile, stdin, stdout, stderr, fdToHandle etc.