2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[System]{Module @System@}
9 ExitCode(ExitSuccess,ExitFailure),
10 getArgs, getProgName, getEnv, system, exitWith
13 import Foreign ( Addr )
14 import IOBase ( IOError(..), thenIO_Prim, constructErrorAndFail )
15 import ArrBase ( indexAddrOffAddr )
16 import PackedString ( unpackCString )
19 %*********************************************************
21 \subsection{The @ExitCode@ type}
23 %*********************************************************
25 The $ExitCode$ type defines the exit codes that a program
26 can return. $ExitSuccess$ indicates successful termination;
27 and $ExitFailure code$ indicates program failure
28 with value {\em code}. The exact interpretation of {\em code}
29 is operating-system dependent. In particular, some values of
30 {\em code} may be prohibited (e.g. 0 on a POSIX-compliant system).
33 data ExitCode = ExitSuccess | ExitFailure Int
34 deriving (Eq, Ord, Read, Show)
39 %*********************************************************
41 \subsection{Other functions}
43 %*********************************************************
46 getArgs :: IO [String]
47 getProgName :: IO String
48 getEnv :: String -> IO String
49 system :: String -> IO ExitCode
50 exitWith :: ExitCode -> IO a
53 Computation $getArgs$ returns a list of the program's command
54 line arguments (not including the program name).
57 getArgs = return (unpackArgv ``prog_argv'' (``prog_argc''::Int))
60 Computation $getProgName$ returns the name of the program
64 getProgName = return (unpackProgName ``prog_argv'')
67 Computation $getEnv var$ returns the value
68 of the environment variable {\em var}.
70 This computation may fail with
73 The environment variable does not exist.
78 _ccall_ getenv name `thenIO_Prim` \ litstring ->
79 if litstring /= ``NULL'' then
80 return (unpackCString litstring)
82 fail (NoSuchThing ("environment variable: " ++ name))
85 Computation $system cmd$ returns the exit code
86 produced when the operating system processes the command {\em cmd}.
88 This computation may fail with
90 \item $PermissionDenied$
91 The process has insufficient privileges to perform the operation.
92 \item $ResourceExhausted$
93 Insufficient resources are available to perform the operation.
94 \item $UnsupportedOperation$
95 The implementation does not support system calls.
99 system "" = fail (InvalidArgument "null command")
101 _ccall_ systemCmd cmd `thenIO_Prim` \ status ->
103 0 -> return ExitSuccess
104 -1 -> constructErrorAndFail "system"
105 n -> return (ExitFailure n)
109 Computation $exitWith code$ terminates the
110 program, returning {\em code} to the program's caller.
111 Before it terminates, any open or semi-closed handles are first closed.
114 exitWith ExitSuccess =
115 _ccall_ EXIT (0::Int) `thenIO_Prim` \ () ->
116 fail (OtherError "exit should not return")
118 exitWith (ExitFailure n)
119 | n == 0 = fail (InvalidArgument "ExitFailure 0")
121 _ccall_ EXIT n `thenIO_Prim` \ () ->
122 fail (OtherError "exit should not return")
126 %*********************************************************
128 \subsection{Local utilities}
130 %*********************************************************
133 type CHAR_STAR_STAR = Addr -- this is all a HACK
134 type CHAR_STAR = Addr
136 unpackArgv :: CHAR_STAR_STAR -> Int -> [String] -- argv[1 .. argc-1]
137 unpackProgName :: CHAR_STAR_STAR -> String -- argv[0]
139 unpackArgv argv argc = unpack 1
141 unpack :: Int -> [String]
144 then ([] :: [String])
145 else case (indexAddrOffAddr argv n) of { item ->
146 unpackCString item : unpack (n + 1) }
149 = case (indexAddrOffAddr argv 0) of { prog ->
150 de_slash [] (unpackCString prog) }
152 -- re-start accumulating at every '/'
153 de_slash :: String -> String -> String
154 de_slash acc [] = reverse acc
155 de_slash acc ('/':xs) = de_slash [] xs
156 de_slash acc (x:xs) = de_slash (x:acc) xs