1 -----------------------------------------------------------------------------
3 -- Module : System.Environment
4 -- Copyright : (c) The University of Glasgow 2001
5 -- License : BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer : libraries@haskell.org
8 -- Stability : provisional
9 -- Portability : portable
11 -- Miscellaneous information about the system environment.
13 -----------------------------------------------------------------------------
15 module System.Environment
17 getArgs, -- :: IO [String]
18 getProgName, -- :: IO String
19 getEnv, -- :: String -> IO String
20 #ifdef __GLASGOW_HASKELL__
28 import Control.Exception ( bracket )
31 #ifdef __GLASGOW_HASKELL__
50 -- ---------------------------------------------------------------------------
51 -- getArgs, getProgName, getEnv
53 -- Computation `getArgs' returns a list of the program's command
54 -- line arguments (not including the program name).
56 #ifdef __GLASGOW_HASKELL__
57 getArgs :: IO [String]
60 alloca $ \ p_argv -> do
61 getProgArgv p_argc p_argv
62 p <- fromIntegral `liftM` peek p_argc
64 peekArray (p - 1) (advancePtr argv 1) >>= mapM peekCString
67 foreign import ccall unsafe "getProgArgv"
68 getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
71 Computation 'getProgName' returns the name of the program as it was
74 However, this is hard-to-impossible to implement on some non-Unix
75 OSes, so instead, for maximum portability, we just return the leafname
76 of the program as invoked. Even then there are some differences
77 between platforms: on Windows, for example, a program invoked as foo
78 is probably really @FOO.EXE@, and that is what 'getProgName' will return.
80 getProgName :: IO String
83 alloca $ \ p_argv -> do
84 getProgArgv p_argc p_argv
88 unpackProgName :: Ptr (Ptr CChar) -> IO String -- argv[0]
89 unpackProgName argv = do
90 s <- peekElemOff argv 0 >>= peekCString
93 basename :: String -> String
98 | isPathSeparator x = go xs xs
99 | otherwise = go acc xs
101 isPathSeparator :: Char -> Bool
102 isPathSeparator '/' = True
103 #ifdef mingw32_TARGET_OS
104 isPathSeparator '\\' = True
106 isPathSeparator _ = False
109 -- Computation `getEnv var' returns the value
110 -- of the environment variable {\em var}.
112 -- This computation may fail with
113 -- NoSuchThing: The environment variable does not exist.
115 getEnv :: String -> IO String
117 withCString name $ \s -> do
118 litstring <- c_getenv s
119 if litstring /= nullPtr
120 then peekCString litstring
121 else ioException (IOError Nothing NoSuchThing "getEnv"
122 "no environment variable" (Just name))
124 foreign import ccall unsafe "getenv"
125 c_getenv :: CString -> IO (Ptr CChar)
128 @withArgs args act@ - while executing action @act@, have 'System.getArgs'
129 return @args@ (GHC only).
132 p <- System.Environment.getProgName
136 @withProgName name act@ - while executing action @act@,
137 have 'System.getProgName' return @name@ (GHC only).
139 withProgName nm act = do
140 xs <- System.Environment.getArgs
143 -- Worker routine which marshals and replaces an argv vector for
144 -- the duration of an action.
146 withArgv new_args act = do
147 pName <- System.Environment.getProgName
148 existing_args <- System.Environment.getArgs
149 bracket (setArgs new_args)
150 (\argv -> do setArgs (pName:existing_args); freeArgv argv)
153 freeArgv :: Ptr CString -> IO ()
155 size <- lengthArray0 nullPtr argv
156 sequence_ [peek (argv `advancePtr` i) >>= free | i <- [size, size-1 .. 0]]
159 setArgs :: [String] -> IO (Ptr CString)
161 vs <- mapM newCString argv >>= newArray0 nullPtr
162 setArgsPrim (length argv) vs
165 foreign import ccall unsafe "setProgArgv"
166 setArgsPrim :: Int -> Ptr CString -> IO ()
167 #endif /* __GLASGOW_HASKELL__ */