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
25 import System.IO ( bracket )
33 #ifdef __GLASGOW_HASKELL__
41 -- ---------------------------------------------------------------------------
42 -- getArgs, getProgName, getEnv
44 -- Computation `getArgs' returns a list of the program's command
45 -- line arguments (not including the program name).
48 getArgs :: IO [String]
51 alloca $ \ p_argv -> do
52 getProgArgv p_argc p_argv
53 p <- fromIntegral `liftM` peek p_argc
55 peekArray (p - 1) (advancePtr argv 1) >>= mapM peekCString
58 foreign import ccall unsafe "getProgArgv"
59 getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
62 Computation 'getProgName' returns the name of the program as it was
65 However, this is hard-to-impossible to implement on some non-Unix
66 OSes, so instead, for maximum portability, we just return the leafname
67 of the program as invoked. Even then there are some differences
68 between platforms: on Windows, for example, a program invoked as foo
69 is probably really @FOO.EXE@, and that is what 'getProgName' will return.
71 getProgName :: IO String
74 alloca $ \ p_argv -> do
75 getProgArgv p_argc p_argv
79 unpackProgName :: Ptr (Ptr CChar) -> IO String -- argv[0]
80 unpackProgName argv = do
81 s <- peekElemOff argv 0 >>= peekCString
84 basename :: String -> String
89 | isPathSeparator x = go xs xs
90 | otherwise = go acc xs
92 isPathSeparator :: Char -> Bool
93 isPathSeparator '/' = True
94 #ifdef mingw32_TARGET_OS
95 isPathSeparator '\\' = True
97 isPathSeparator _ = False
100 -- Computation `getEnv var' returns the value
101 -- of the environment variable {\em var}.
103 -- This computation may fail with
104 -- NoSuchThing: The environment variable does not exist.
106 getEnv :: String -> IO String
108 withCString name $ \s -> do
109 litstring <- c_getenv s
110 if litstring /= nullPtr
111 then peekCString litstring
112 else ioException (IOError Nothing NoSuchThing "getEnv"
113 "no environment variable" (Just name))
115 foreign import ccall unsafe "getenv"
116 c_getenv :: CString -> IO (Ptr CChar)
117 #endif /* __HUGS__ */
120 @withArgs args act@ - while executing action @act@, have 'System.getArgs'
124 p <- System.Environment.getProgName
128 @withProgName name act@ - while executing action @act@, have 'System.getProgName'return @name@.
130 withProgName nm act = do
131 xs <- System.Environment.getArgs
134 -- Worker routine which marshals and replaces an argv vector for
135 -- the duration of an action.
137 withArgv new_args act = do
138 pName <- System.Environment.getProgName
139 existing_args <- System.Environment.getArgs
140 bracket (setArgs new_args)
141 (\argv -> do setArgs (pName:existing_args); freeArgv argv)
144 freeArgv :: Ptr CString -> IO ()
146 size <- lengthArray0 nullPtr argv
147 sequence_ [peek (argv `advancePtr` i) >>= free | i <- [size, size-1 .. 0]]
150 setArgs :: [String] -> IO (Ptr CString)
152 vs <- mapM newCString argv >>= newArray0 nullPtr
153 setArgsPrim (length argv) vs
156 foreign import ccall unsafe "setProgArgv"
157 setArgsPrim :: Int -> Ptr CString -> IO ()