2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[System]{Module @System@}
9 ExitCode(ExitSuccess,ExitFailure),
10 getArgs, getProgName, getEnv, system, exitWith
14 import Foreign ( Addr )
15 import IOBase ( IOError(..), IOErrorType(..), thenIO_Prim, constructErrorAndFail )
16 import ArrBase ( indexAddrOffAddr )
17 import PackedString ( unpackCString )
21 %*********************************************************
23 \subsection{The @ExitCode@ type}
25 %*********************************************************
27 The $ExitCode$ type defines the exit codes that a program
28 can return. $ExitSuccess$ indicates successful termination;
29 and $ExitFailure code$ indicates program failure
30 with value {\em code}. The exact interpretation of {\em code}
31 is operating-system dependent. In particular, some values of
32 {\em code} may be prohibited (e.g. 0 on a POSIX-compliant system).
35 data ExitCode = ExitSuccess | ExitFailure Int
36 deriving (Eq, Ord, Read, Show)
41 %*********************************************************
43 \subsection{Other functions}
45 %*********************************************************
48 getArgs :: IO [String]
49 getProgName :: IO String
50 getEnv :: String -> IO String
51 system :: String -> IO ExitCode
52 exitWith :: ExitCode -> IO a
55 Computation $getArgs$ returns a list of the program's command
56 line arguments (not including the program name).
59 getArgs = return (unpackArgv ``prog_argv'' (``prog_argc''::Int))
62 Computation $getProgName$ returns the name of the program
66 getProgName = return (unpackProgName ``prog_argv'')
69 Computation $getEnv var$ returns the value
70 of the environment variable {\em var}.
72 This computation may fail with
75 The environment variable does not exist.
80 _ccall_ getenv name `thenIO_Prim` \ litstring ->
81 if litstring /= ``NULL'' then
82 return (unpackCString litstring)
84 fail (IOError Nothing NoSuchThing ("environment variable: " ++ name))
87 Computation $system cmd$ returns the exit code
88 produced when the operating system processes the command {\em cmd}.
90 This computation may fail with
92 \item $PermissionDenied$
93 The process has insufficient privileges to perform the operation.
94 \item $ResourceExhausted$
95 Insufficient resources are available to perform the operation.
96 \item $UnsupportedOperation$
97 The implementation does not support system calls.
101 system "" = fail (IOError Nothing InvalidArgument "null command")
103 _ccall_ systemCmd cmd `thenIO_Prim` \ status ->
105 0 -> return ExitSuccess
106 -1 -> constructErrorAndFail "system"
107 n -> return (ExitFailure n)
111 Computation $exitWith code$ terminates the
112 program, returning {\em code} to the program's caller.
113 Before it terminates, any open or semi-closed handles are first closed.
116 exitWith ExitSuccess =
117 _ccall_ EXIT (0::Int) `thenIO_Prim` \ () ->
118 fail (IOError Nothing OtherError "exit should not return")
120 exitWith (ExitFailure n)
121 | n == 0 = fail (IOError Nothing InvalidArgument "ExitFailure 0")
123 _ccall_ EXIT n `thenIO_Prim` \ () ->
124 fail (IOError Nothing OtherError "exit should not return")
128 %*********************************************************
130 \subsection{Local utilities}
132 %*********************************************************
135 type CHAR_STAR_STAR = Addr -- this is all a HACK
136 type CHAR_STAR = Addr
138 unpackArgv :: CHAR_STAR_STAR -> Int -> [String] -- argv[1 .. argc-1]
139 unpackProgName :: CHAR_STAR_STAR -> String -- argv[0]
141 unpackArgv argv argc = unpack 1
143 unpack :: Int -> [String]
146 then ([] :: [String])
147 else case (indexAddrOffAddr argv n) of { item ->
148 unpackCString item : unpack (n + 1) }
151 = case (indexAddrOffAddr argv 0) of { prog ->
152 de_slash [] (unpackCString prog) }
154 -- re-start accumulating at every '/'
155 de_slash :: String -> String -> String
156 de_slash acc [] = reverse acc
157 de_slash acc ('/':xs) = de_slash [] xs
158 de_slash acc (x:xs) = de_slash (x:acc) xs