... |
... |
@@ -79,7 +79,11 @@ module GHC.IO.Handle |
79
|
79
|
withFileDescriptorReadingBiased,
|
80
|
80
|
withFileDescriptorWritingBiased,
|
81
|
81
|
withWindowsHandleReadingBiased,
|
82
|
|
- withWindowsHandleWritingBiased
|
|
82
|
+ withWindowsHandleWritingBiased,
|
|
83
|
+ withFileDescriptorReadingBiasedRaw,
|
|
84
|
+ withFileDescriptorWritingBiasedRaw,
|
|
85
|
+ withWindowsHandleReadingBiasedRaw,
|
|
86
|
+ withWindowsHandleWritingBiasedRaw
|
83
|
87
|
|
84
|
88
|
-- ** Caveats
|
85
|
89
|
-- $with-ref-caveats
|
... |
... |
@@ -90,7 +94,7 @@ import GHC.Internal.IO.Handle |
90
|
94
|
import GHC.Internal.Control.Monad (return)
|
91
|
95
|
import GHC.Internal.Control.Concurrent.MVar (MVar)
|
92
|
96
|
import GHC.Internal.Control.Exception (mask)
|
93
|
|
-import GHC.Internal.Data.Function ((.), ($))
|
|
97
|
+import GHC.Internal.Data.Function (const, (.), ($))
|
94
|
98
|
import GHC.Internal.Data.Functor (fmap)
|
95
|
99
|
#if defined(mingw32_HOST_OS)
|
96
|
100
|
import GHC.Internal.Data.Bool (otherwise)
|
... |
... |
@@ -132,11 +136,11 @@ import GHC.Internal.Foreign.C.Types (CInt) |
132
|
136
|
|
133
|
137
|
{-|
|
134
|
138
|
Obtains an operating-system handle that underlies a Haskell handle and
|
135
|
|
- executes a user-provided action on it. The Haskell-managed buffers related
|
136
|
|
- to the operating-system handle are flushed before the user-provided action
|
137
|
|
- is run. While this action is executed, further operations on the Haskell
|
138
|
|
- handle are blocked to a degree that interference with this action is
|
139
|
|
- prevented.
|
|
139
|
+ executes a user-provided action on it. Before the user-provided action is
|
|
140
|
+ run, user-defined perparation based on the handle state that contains the
|
|
141
|
+ operating-system handle is performed. While the user-provided action is
|
|
142
|
+ executed, further operations on the Haskell handle are blocked to a degree
|
|
143
|
+ that interference with this action is prevented.
|
140
|
144
|
|
141
|
145
|
See [below](#with-ref-caveats) for caveats regarding this operation.
|
142
|
146
|
-}
|
... |
... |
@@ -149,16 +153,18 @@ withOSHandle :: String |
149
|
153
|
-}
|
150
|
154
|
-> (forall d. Typeable d => d -> IO a)
|
151
|
155
|
-- ^ Conversion of a device into an operating-system handle
|
|
156
|
+ -> (Handle__ -> IO ())
|
|
157
|
+ -- ^ The preparation
|
152
|
158
|
-> Handle
|
153
|
159
|
-- ^ The Haskell handle to use
|
154
|
160
|
-> (a -> IO r)
|
155
|
161
|
-- ^ The action to execute on the operating-system handle
|
156
|
162
|
-> IO r
|
157
|
|
-withOSHandle opName handleStateVar getOSHandle handle act
|
|
163
|
+withOSHandle opName handleStateVar getOSHandle prepare handle act
|
158
|
164
|
= mask $ \ withOriginalMaskingState ->
|
159
|
165
|
withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
|
160
|
166
|
osHandle <- getOSHandle dev
|
161
|
|
- flushBuffer handleState
|
|
167
|
+ prepare handleState
|
162
|
168
|
withOriginalMaskingState $ act osHandle
|
163
|
169
|
where
|
164
|
170
|
|
... |
... |
@@ -272,6 +278,7 @@ withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r |
272
|
278
|
withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
|
273
|
279
|
handleStateVarReadingBiased
|
274
|
280
|
getFileDescriptor
|
|
281
|
+ flushBuffer
|
275
|
282
|
|
276
|
283
|
{-|
|
277
|
284
|
Obtains the POSIX file descriptor that underlies a handle or specifically
|
... |
... |
@@ -290,6 +297,7 @@ withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r |
290
|
297
|
withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
|
291
|
298
|
handleStateVarWritingBiased
|
292
|
299
|
getFileDescriptor
|
|
300
|
+ flushBuffer
|
293
|
301
|
|
294
|
302
|
{-|
|
295
|
303
|
Obtains the Windows handle that underlies a Haskell handle or specifically
|
... |
... |
@@ -308,6 +316,7 @@ withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r |
308
|
316
|
withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
|
309
|
317
|
handleStateVarReadingBiased
|
310
|
318
|
getWindowsHandle
|
|
319
|
+ flushBuffer
|
311
|
320
|
|
312
|
321
|
{-|
|
313
|
322
|
Obtains the Windows handle that underlies a Haskell handle or specifically
|
... |
... |
@@ -326,17 +335,62 @@ withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r |
326
|
335
|
withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
|
327
|
336
|
handleStateVarWritingBiased
|
328
|
337
|
getWindowsHandle
|
|
338
|
+ flushBuffer
|
|
339
|
+
|
|
340
|
+{-|
|
|
341
|
+ Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
|
|
342
|
+ are not flushed.
|
|
343
|
+-}
|
|
344
|
+withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
|
|
345
|
+withFileDescriptorReadingBiasedRaw
|
|
346
|
+ = withOSHandle "withFileDescriptorReadingBiasedRaw"
|
|
347
|
+ handleStateVarReadingBiased
|
|
348
|
+ getFileDescriptor
|
|
349
|
+ (const $ return ())
|
|
350
|
+
|
|
351
|
+{-|
|
|
352
|
+ Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
|
|
353
|
+ are not flushed.
|
|
354
|
+-}
|
|
355
|
+withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
|
|
356
|
+withFileDescriptorWritingBiasedRaw
|
|
357
|
+ = withOSHandle "withFileDescriptorWritingBiasedRaw"
|
|
358
|
+ handleStateVarWritingBiased
|
|
359
|
+ getFileDescriptor
|
|
360
|
+ (const $ return ())
|
|
361
|
+
|
|
362
|
+{-|
|
|
363
|
+ Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
|
|
364
|
+ are not flushed.
|
|
365
|
+-}
|
|
366
|
+withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
|
|
367
|
+withWindowsHandleReadingBiasedRaw
|
|
368
|
+ = withOSHandle "withWindowsHandleReadingBiasedRaw"
|
|
369
|
+ handleStateVarReadingBiased
|
|
370
|
+ getWindowsHandle
|
|
371
|
+ (const $ return ())
|
|
372
|
+
|
|
373
|
+{-|
|
|
374
|
+ Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
|
|
375
|
+ are not flushed.
|
|
376
|
+-}
|
|
377
|
+withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
|
|
378
|
+withWindowsHandleWritingBiasedRaw
|
|
379
|
+ = withOSHandle "withWindowsHandleWritingBiasedRaw"
|
|
380
|
+ handleStateVarWritingBiased
|
|
381
|
+ getWindowsHandle
|
|
382
|
+ (const $ return ())
|
329
|
383
|
|
330
|
384
|
-- ** Caveats
|
331
|
385
|
|
332
|
386
|
{-$with-ref-caveats
|
333
|
|
- #with-ref-caveats#There are the following caveats regarding each of the
|
334
|
|
- above operations:
|
|
387
|
+ #with-ref-caveats#There are the following caveats regarding the above
|
|
388
|
+ operations:
|
335
|
389
|
|
336
|
|
- * The flushing of buffers can fail if the given handle is readable but not
|
|
390
|
+ * Flushing of buffers can fail if the given handle is readable but not
|
337
|
391
|
seekable.
|
338
|
392
|
|
339
|
|
- * If the operation is performed as part of an action executed by
|
|
393
|
+ * If one of these operation is performed as part of an action executed by
|
340
|
394
|
'unsafePerformIO', 'unsafeInterleaveIO', or one of their “dupable”
|
341
|
395
|
variants and the user-provided action receives an asychnchronous
|
342
|
396
|
exception and does not catch it, then the following happens:
|