2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 \section[LibPosixProcEnv]{Haskell 1.3 POSIX Process Environment}
7 module LibPosixProcEnv (
18 getControllingTerminalName,
53 getProcessID :: IO ProcessID
55 _ccall_ getpid `thenPrimIO` \ pid ->
58 getParentProcessID :: IO ProcessID
60 _ccall_ getppid `thenPrimIO` \ ppid ->
63 getRealUserID :: IO UserID
65 _ccall_ getuid `thenPrimIO` \ uid ->
68 getEffectiveUserID :: IO UserID
70 _ccall_ geteuid `thenPrimIO` \ euid ->
73 setUserID :: UserID -> IO ()
75 _ccall_ setuid uid `thenPrimIO` \ rc ->
81 getLoginName :: IO String
83 _ccall_ getlogin `thenPrimIO` \ str ->
84 if str == ``NULL'' then
87 strcpy str `thenPrimIO` \ name ->
90 getRealGroupID :: IO GroupID
92 _ccall_ getgid `thenPrimIO` \ gid ->
95 getEffectiveGroupID :: IO GroupID
97 _ccall_ getegid `thenPrimIO` \ egid ->
100 setGroupID :: GroupID -> IO ()
102 _ccall_ setgid gid `thenPrimIO` \ rc ->
108 getGroups :: IO [GroupID]
110 _ccall_ getgroups 0 (``NULL''::_Addr) `thenPrimIO` \ ngroups ->
111 allocWords ngroups `thenStrictlyST` \ words ->
112 _casm_ ``%r = getgroups(%0,(gid_t *)%1);'' ngroups words
113 `thenPrimIO` \ ngroups ->
114 if ngroups /= -1 then
115 freeze words `thenStrictlyST` \ arr ->
116 return (map (extract arr) [0..(ngroups-1)])
120 extract (_ByteArray _ barr#) (I# n#) =
121 case indexIntArray# barr# n# of
124 getEffectiveUserName :: IO String
125 getEffectiveUserName =
126 _ccall_ cuserid (``NULL''::_Addr) `thenPrimIO` \ str ->
127 if str == ``NULL'' then
128 syserr "getEffectiveUserName"
130 strcpy str `thenPrimIO` \ name ->
133 getProcessGroupID :: IO ProcessGroupID
135 _ccall_ getpgrp `thenPrimIO` \ pgid ->
138 createProcessGroup :: ProcessID -> IO ProcessGroupID
139 createProcessGroup pid =
140 _ccall_ setpgid pid 0 `thenPrimIO` \ pgid ->
144 syserr "createProcessGroup"
146 joinProcessGroup :: ProcessGroupID -> IO ()
147 joinProcessGroup pgid =
148 _ccall_ setpgid 0 pgid `thenPrimIO` \ rc ->
152 syserr "setProcessGroupID"
154 setProcessGroupID :: ProcessID -> ProcessGroupID -> IO ()
155 setProcessGroupID pid pgid =
156 _ccall_ setpgid pid pgid `thenPrimIO` \ rc ->
160 syserr "setProcessGroupID"
162 createSession :: IO ProcessGroupID
164 _ccall_ setsid `thenPrimIO` \ pgid ->
168 syserr "createSession"
170 type SystemID = _ByteArray ()
172 systemName :: SystemID -> String
173 systemName sid = unsafePerformPrimIO (
174 _casm_ ``%r = ((struct utsname *)%0)->sysname;'' sid
175 `thenPrimIO` \ str ->
176 strcpy str `thenPrimIO` \ sysname ->
177 returnPrimIO sysname)
179 nodeName :: SystemID -> String
180 nodeName sid = unsafePerformPrimIO (
181 _casm_ ``%r = ((struct utsname *)%0)->nodename;'' sid
182 `thenPrimIO` \ str ->
183 strcpy str `thenPrimIO` \ nodename ->
184 returnPrimIO nodename)
186 release :: SystemID -> String
187 release sid = unsafePerformPrimIO (
188 _casm_ ``%r = ((struct utsname *)%0)->release;'' sid
189 `thenPrimIO` \ str ->
190 strcpy str `thenPrimIO` \ releaseStr ->
191 returnPrimIO releaseStr)
193 version :: SystemID -> String
194 version sid = unsafePerformPrimIO (
195 _casm_ ``%r = ((struct utsname *)%0)->version;'' sid
196 `thenPrimIO` \ str ->
197 strcpy str `thenPrimIO` \ versionStr ->
198 returnPrimIO versionStr)
200 machine :: SystemID -> String
201 machine sid = unsafePerformPrimIO (
202 _casm_ ``%r = ((struct utsname *)%0)->machine;'' sid
203 `thenPrimIO` \ str ->
204 strcpy str `thenPrimIO` \ machine ->
205 returnPrimIO machine)
207 getSystemID :: IO SystemID
209 allocChars (``sizeof(struct utsname)''::Int) `thenStrictlyST` \ bytes ->
210 _casm_ ``%r = uname((struct utsname *)%0);'' bytes
213 freeze bytes `thenStrictlyST` \ sid ->
218 epochTime :: IO EpochTime
220 _ccall_ time (``NULL''::_Addr) `thenPrimIO` \ secs ->
226 -- All times in clock ticks (see getClockTick)
228 type ProcessTimes = (ClockTick, _ByteArray ())
230 elapsedTime :: ProcessTimes -> ClockTick
231 elapsedTime (realtime, _) = realtime
233 userTime :: ProcessTimes -> ClockTick
234 userTime (_, times) = unsafePerformPrimIO (
235 _casm_ ``%r = ((struct tms *)%0)->tms_utime;'' times
236 `thenStrictlyST` \ utime ->
239 systemTime :: ProcessTimes -> ClockTick
240 systemTime (_, times) = unsafePerformPrimIO (
241 _casm_ ``%r = ((struct tms *)%0)->tms_stime;'' times
242 `thenStrictlyST` \ stime ->
245 childUserTime :: ProcessTimes -> ClockTick
246 childUserTime (_, times) = unsafePerformPrimIO (
247 _casm_ ``%r = ((struct tms *)%0)->tms_cutime;'' times
248 `thenStrictlyST` \ cutime ->
251 childSystemTime :: ProcessTimes -> ClockTick
252 childSystemTime (_, times) = unsafePerformPrimIO (
253 _casm_ ``%r = ((struct tms *)%0)->tms_cstime;'' times
254 `thenStrictlyST` \ cstime ->
257 getProcessTimes :: IO ProcessTimes
259 allocChars (``sizeof(struct tms)''::Int) `thenStrictlyST` \ bytes ->
260 _casm_ ``%r = times((struct tms *)%0);'' bytes `thenPrimIO` \ elapsed ->
261 if elapsed /= -1 then
262 freeze bytes `thenStrictlyST` \ times ->
263 return (elapsed, times)
265 syserr "getProcessTimes"
267 getControllingTerminalName :: IO FilePath
268 getControllingTerminalName =
269 _ccall_ ctermid (``NULL''::_Addr) `thenPrimIO` \ str ->
270 if str == ``NULL'' then
271 failWith (NoSuchThing "no controlling terminal")
273 strcpy str `thenPrimIO` \ name ->
276 getTerminalName :: Channel -> IO FilePath
278 _ccall_ ttyname fd `thenPrimIO` \ str ->
279 if str == ``NULL'' then
280 try (queryTerminal fd) >>=
281 either (\err -> syserr "getTerminalName")
282 (\succ -> if succ then failWith (NoSuchThing "terminal name")
283 else failWith (InappropriateType "not a terminal"))
285 strcpy str `thenPrimIO` \ name ->
288 queryTerminal :: Channel -> IO Bool
290 _ccall_ isatty fd `thenPrimIO` \ rc ->
292 -1 -> syserr "queryTerminal"
296 data SysVar = ArgumentLimit
305 getSysVar :: SysVar -> IO Limit
308 ArgumentLimit -> sysconf ``_SC_ARG_MAX''
309 ChildLimit -> sysconf ``_SC_CHILD_MAX''
310 ClockTick -> sysconf ``_SC_CLK_TCK''
311 GroupLimit -> sysconf ``_SC_NGROUPS_MAX''
312 OpenFileLimit -> sysconf ``_SC_OPEN_MAX''
313 PosixVersion -> sysconf ``_SC_VERSION''
314 HasSavedIDs -> sysconf ``_SC_SAVED_IDS''
315 HasJobControl -> sysconf ``_SC_JOB_CONTROL''
317 sysconf :: Int -> IO Limit
319 _ccall_ sysconf n `thenPrimIO` \ rc ->
323 failWith (NoSuchThing "no such system limit or option")