diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-07-16 10:56:54 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-07-16 10:56:54 -0400 |
commit | c0979cc53442b3a6202acab9cf164f0a4beea0b7 (patch) | |
tree | d08b956887e69f9bd2959f1ac75cc2a2182f9a32 /libraries/base/System | |
parent | ae11bdfd98a10266bfc7de9e16b500be220307ac (diff) | |
parent | 2143c49273d7d87ee2f3ef1211856d60b1427af1 (diff) | |
download | haskell-c0979cc53442b3a6202acab9cf164f0a4beea0b7.tar.gz |
Merge remote-tracking branch 'origin/wip/winio'
Diffstat (limited to 'libraries/base/System')
-rw-r--r-- | libraries/base/System/IO.hs | 51 | ||||
-rw-r--r-- | libraries/base/System/Timeout.hs | 2 |
2 files changed, 44 insertions, 9 deletions
diff --git a/libraries/base/System/IO.hs b/libraries/base/System/IO.hs index a4d4ec4e67..03e0e06319 100644 --- a/libraries/base/System/IO.hs +++ b/libraries/base/System/IO.hs @@ -232,6 +232,12 @@ import Foreign.C.String import Foreign.Ptr import Foreign.Marshal.Alloc import Foreign.Storable +import GHC.IO.SubSystem +import GHC.IO.Windows.Handle (openFileAsTemp) +import GHC.IO.Handle.Windows (mkHandleFromHANDLE) +import GHC.IO.Device as IODevice +import GHC.Real (fromIntegral) +import Foreign.Marshal.Utils (new) #endif import Foreign.C.Types import System.Posix.Internals @@ -245,13 +251,14 @@ import GHC.IORef import GHC.Num import GHC.IO hiding ( bracket, onException ) import GHC.IO.IOMode -import GHC.IO.Handle.FD import qualified GHC.IO.FD as FD import GHC.IO.Handle +import qualified GHC.IO.Handle.FD as POSIX import GHC.IO.Handle.Text ( hGetBufSome, hPutStrLn ) import GHC.IO.Exception ( userError ) import GHC.IO.Encoding import Text.Read +import GHC.IO.StdHandles import GHC.Show import GHC.MVar @@ -529,13 +536,29 @@ openTempFile' loc tmp_dir template binary mode -- beginning with '.' as the second component. _ -> errorWithoutStackTrace "bug in System.IO.openTempFile" #if defined(mingw32_HOST_OS) - findTempName = do + findTempName = findTempNamePosix <!> findTempNameWinIO + + findTempNameWinIO = do + let label = if null prefix then "ghc" else prefix + withCWString tmp_dir $ \c_tmp_dir -> + withCWString label $ \c_template -> + withCWString suffix $ \c_suffix -> do + c_ptr <- new nullPtr + res <- c_createUUIDTempFileErrNo c_tmp_dir c_template c_suffix + c_ptr + if not res + then do errno <- getErrno + ioError (errnoToIOError loc errno Nothing (Just tmp_dir)) + else do c_p <- peek c_ptr + filename <- peekCWString c_p + free c_p + handleResultsWinIO filename ((fromIntegral mode .&. o_EXCL) == o_EXCL) + + findTempNamePosix = do let label = if null prefix then "ghc" else prefix withCWString tmp_dir $ \c_tmp_dir -> withCWString label $ \c_template -> withCWString suffix $ \c_suffix -> - -- NOTE: revisit this when new I/O manager in place and use a UUID - -- based one when we are no longer MAX_PATH bound. allocaBytes (sizeOf (undefined :: CWchar) * 260) $ \c_str -> do res <- c_getTempFileNameErrorNo c_tmp_dir c_template c_suffix 0 c_str @@ -543,9 +566,9 @@ openTempFile' loc tmp_dir template binary mode then do errno <- getErrno ioError (errnoToIOError loc errno Nothing (Just tmp_dir)) else do filename <- peekCWString c_str - handleResults filename + handleResultsPosix filename - handleResults filename = do + handleResultsPosix filename = do let oflags1 = rw_flags .|. o_EXCL binary_flags | binary = o_BINARY @@ -561,14 +584,26 @@ openTempFile' loc tmp_dir template binary mode True{-is_nonblock-} enc <- getLocaleEncoding - h <- mkHandleFromFD fD fd_type filename ReadWriteMode + h <- POSIX.mkHandleFromFD fD fd_type filename ReadWriteMode False{-set non-block-} (Just enc) return (filename, h) + handleResultsWinIO filename excl = do + (hwnd, hwnd_type) <- openFileAsTemp filename True excl + mb_codec <- if binary then return Nothing else fmap Just getLocaleEncoding + + -- then use it to make a Handle + h <- mkHandleFromHANDLE hwnd hwnd_type filename ReadWriteMode mb_codec + `onException` IODevice.close hwnd + return (filename, h) + foreign import ccall "getTempFileNameErrorNo" c_getTempFileNameErrorNo :: CWString -> CWString -> CWString -> CUInt -> Ptr CWchar -> IO Bool +foreign import ccall "__createUUIDTempFileErrNo" c_createUUIDTempFileErrNo + :: CWString -> CWString -> CWString -> Ptr CWString -> IO Bool + pathSeparator :: String -> Bool pathSeparator template = any (\x-> x == '/' || x == '\\') template @@ -588,7 +623,7 @@ output_flags = std_flags True{-is_nonblock-} enc <- getLocaleEncoding - h <- mkHandleFromFD fD fd_type filepath ReadWriteMode False{-set non-block-} (Just enc) + h <- POSIX.mkHandleFromFD fD fd_type filepath ReadWriteMode False{-set non-block-} (Just enc) return (filepath, h) diff --git a/libraries/base/System/Timeout.hs b/libraries/base/System/Timeout.hs index df2c0f055a..1c41dc2ca2 100644 --- a/libraries/base/System/Timeout.hs +++ b/libraries/base/System/Timeout.hs @@ -15,7 +15,7 @@ -- Attach a timeout event to arbitrary 'IO' computations. -- ------------------------------------------------------------------------------- - +-- TODO: Inspect is still suitable. module System.Timeout ( Timeout, timeout ) where #if !defined(mingw32_HOST_OS) |