[commit: base] encoding: Use RTS-carried argv on Windows again (e65910c)
Max Bolingbroke
batterseapower at hotmail.com
Tue Apr 12 13:25:47 CEST 2011
Repository : ssh://darcs.haskell.org//srv/darcs/packages/base
On branch : encoding
http://hackage.haskell.org/trac/ghc/changeset/e65910c5cbe520e4782ef8793c49c4e2b9bb4e7a
>---------------------------------------------------------------
commit e65910c5cbe520e4782ef8793c49c4e2b9bb4e7a
Author: Max Bolingbroke <batterseapower at hotmail.com>
Date: Tue Apr 12 12:07:04 2011 +0100
Use RTS-carried argv on Windows again
>---------------------------------------------------------------
System/Environment.hs | 54 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/System/Environment.hs b/System/Environment.hs
index 39c9d9f..cf73c3d 100644
--- a/System/Environment.hs
+++ b/System/Environment.hs
@@ -42,7 +42,6 @@ import Data.List
#ifdef mingw32_HOST_OS
import GHC.Environment
import GHC.Windows
-import Data.IORef
#else
import Control.Monad
#endif
@@ -66,12 +65,44 @@ import System
#ifdef mingw32_HOST_OS
-{-# NOINLINE argsRef #-}
-argsRef :: IORef [String]
-argsRef = unsafePerformIO $ do
- -- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
- init_args <- fmap dropRTSArgs getFullArgs
- newIORef init_args
+-- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
+
+getWin32ProgArgv_certainly :: IO [String]
+getWin32ProgArgv_certainly = do
+ mb_argv <- getWin32ProgArgv
+ case mb_argv of
+ Nothing -> fmap dropRTSArgs getFullArgs
+ Just argv -> return argv
+
+withWin32ProgArgv :: [String] -> IO a -> IO a
+withWin32ProgArgv argv act = bracket begin setWin32ProgArgv (\_ -> act)
+ where
+ begin = do
+ mb_old_argv <- getWin32ProgArgv
+ setWin32ProgArgv (Just argv)
+ return mb_old_argv
+
+getWin32ProgArgv :: IO (Maybe [String])
+getWin32ProgArgv = alloca $ \p_argc -> alloca $ \p_argv -> do
+ c_getWin32ProgArgv p_argc p_argv
+ argc <- peek p_argc
+ argv_p <- peek p_argv
+ if argv_p == nullPtr
+ then return Nothing
+ else do
+ argv_ps <- peekArray (fromIntegral argc) argv_p
+ fmap Just $ mapM peekCWString argv_ps
+
+setWin32ProgArgv :: Maybe [String] -> IO ()
+setWin32ProgArgv Nothing = c_setWin32ProgArgv 0 nullPtr
+setWin32ProgArgv (Just argv) = withMany withCWString argv $ \argv_ps -> withArrayLen argv_ps $ \argc argv_p -> do
+ c_setWin32ProgArgv (fromIntegral argc) argv_p
+
+foreign import ccall unsafe "getWin32ProgArgv"
+ c_getWin32ProgArgv :: Ptr CInt -> Ptr (Ptr CWString) -> IO ()
+
+foreign import ccall unsafe "setWin32ProgArgv"
+ c_setWin32ProgArgv :: CInt -> Ptr CWString -> IO ()
dropRTSArgs :: [String] -> [String]
dropRTSArgs [] = []
@@ -87,7 +118,7 @@ dropRTSArgs (arg:rest) = arg : dropRTSArgs rest
getArgs :: IO [String]
#ifdef mingw32_HOST_OS
-getArgs = fmap tail (readIORef argsRef)
+getArgs = fmap tail getWin32ProgArgv_certainly
#else
getArgs =
alloca $ \ p_argc ->
@@ -114,7 +145,7 @@ is probably really @FOO.EXE@, and that is what 'getProgName' will return.
getProgName :: IO String
#ifdef mingw32_HOST_OS
-- Ignore the arguments to hs_init on Windows for the sake of Unicode compat
-getProgName = fmap (basename . head) (readIORef argsRef)
+getProgName = fmap (basename . head) getWin32ProgArgv_certainly
#else
getProgName =
alloca $ \ p_argc ->
@@ -219,10 +250,7 @@ withArgv :: [String] -> IO a -> IO a
-- We have to reflect the updated arguments in the RTS-side variables as
-- well, because the RTS still consults them for error messages and the like.
-- If we don't do this then ghc-e005 fails.
-withArgv new_args act = bracket (setArgs new_args) setArgs (\_ -> withProgArgv new_args act)
-
-setArgs :: [String] -> IO [String]
-setArgs argv = atomicModifyIORef argsRef $ \old_argv -> (argv, old_argv)
+withArgv new_args act = withWin32ProgArgv new_args $ withProgArgv new_args act
#else
withArgv = withProgArgv
#endif
More information about the Cvs-libraries
mailing list