------------------------------------------------------------------------------ --- Library to access parts of the system environment. --- --- @author Michael Hanus, Bernd Brassel, Bjoern Peemoeller --- @version July 2012 --- @category general ------------------------------------------------------------------------------ module System ( getCPUTime,getElapsedTime , getArgs, getEnviron, setEnviron, unsetEnviron, getProgName , getHostname, getPID, system, exitWith, sleep , isPosix, isWindows ) where import Global ( Global, GlobalSpec(..), global, readGlobal, writeGlobal ) --- Returns the current cpu time of the process in milliseconds. getCPUTime :: IO Int getCPUTime external --- Returns the current elapsed time of the process in milliseconds. --- This operation is not supported in KiCS2 (there it always returns 0), --- but only included for compatibility reasons. getElapsedTime :: IO Int getElapsedTime external --- Returns the list of the program's command line arguments. --- The program name is not included. getArgs :: IO [String] getArgs external --- Returns the value of an environment variable. --- The empty string is returned for undefined environment variables. getEnviron :: String -> IO String getEnviron evar = do envs <- readGlobal environ maybe (prim_getEnviron $## evar) return (lookup evar envs) prim_getEnviron :: String -> IO String prim_getEnviron external --- internal state of environment variables set via setEnviron environ :: Global [(String,String)] environ = global [] Temporary --- Set an environment variable to a value. --- The new value will be passed to subsequent shell commands --- (see system) and visible to subsequent calls to --- getEnviron (but it is not visible in the environment --- of the process that started the program execution). setEnviron :: String -> String -> IO () setEnviron evar val = do envs <- readGlobal environ writeGlobal environ ((evar,val) : filter ((/=evar) . fst) envs) --- Removes an environment variable that has been set by --- setEnviron. unsetEnviron :: String -> IO () unsetEnviron evar = do envs <- readGlobal environ writeGlobal environ (filter ((/=evar) . fst) envs) --- Returns the hostname of the machine running this process. getHostname :: IO String getHostname external --- Returns the process identifier of the current Curry process. getPID :: IO Int getPID external --- Returns the name of the current program, i.e., the name of the --- main module currently executed. getProgName :: IO String getProgName external --- Executes a shell command and return with the exit code of the command. --- An exit status of zero means successful execution. system :: String -> IO Int system cmd = do envs <- readGlobal environ prim_system $## (concatMap envToExport envs ++ escapedCmd) where win = isWindows -- This is a work around for GHC ticket #5376 -- (http://hackage.haskell.org/trac/ghc/ticket/5376) escapedCmd = if win then '\"' : cmd ++ "\"" else cmd envToExport (var, val) = if win then "set " ++ var ++ "=" ++ concatMap escapeWinSpecials val ++ " && " else var ++ "='" ++ concatMap encodeShellSpecials val ++ "' ; export " ++ var ++ " ; " escapeWinSpecials c = if c `elem` "<>|&^" then ['^', c] else [c] encodeShellSpecials c = if c == '\'' then map chr [39,34,39,34,39] else [c] prim_system :: String -> IO Int prim_system external --- Terminates the execution of the current Curry program --- and returns the exit code given by the argument. --- An exit code of zero means successful execution. exitWith :: Int -> IO _ exitWith exitcode = prim_exitWith $# exitcode prim_exitWith :: Int -> IO _ prim_exitWith external --- The evaluation of the action (sleep n) puts the Curry process --- asleep for n seconds. sleep :: Int -> IO () sleep n = prim_sleep $# n prim_sleep :: Int -> IO () prim_sleep external --- Is the underlying operating system a POSIX system (unix, MacOS)? isPosix :: Bool isPosix = not isWindows --- Is the underlying operating system a Windows system? isWindows :: Bool isWindows external