2 % (c) The GRASP/AQUA Project, Glasgow University, 1995-1996
4 \section[PosixProcEnv]{Haskell 1.3 POSIX Process Environment}
17 #if !defined(cygwin32_TARGET_OS)
18 getControllingTerminalName,
23 #if !defined(cygwin32_TARGET_OS)
51 import PrelArr (ByteArray(..)) -- see internals
58 getProcessID :: IO ProcessID
59 getProcessID = _ccall_ getpid
61 getParentProcessID :: IO ProcessID
62 getParentProcessID = _ccall_ getppid
64 getRealUserID :: IO UserID
65 getRealUserID = _ccall_ getuid
67 getEffectiveUserID :: IO UserID
68 getEffectiveUserID = _ccall_ geteuid
70 setUserID :: UserID -> IO ()
71 setUserID uid = nonzero_error (_ccall_ setuid uid) "setUserID"
73 getLoginName :: IO String
75 str <- _ccall_ getlogin
77 then syserr "getLoginName"
80 getRealGroupID :: IO GroupID
81 getRealGroupID = _ccall_ getgid
83 getEffectiveGroupID :: IO GroupID
84 getEffectiveGroupID = _ccall_ getegid
86 setGroupID :: GroupID -> IO ()
87 setGroupID gid = nonzero_error (_ccall_ setgid gid) "setGroupID"
89 -- getgroups() is not supported in beta18 of
91 #if !defined(cygwin32_TARGET_OS)
92 getGroups :: IO [GroupID]
94 ngroups <- _ccall_ getgroups 0 (``NULL''::Addr)
95 words <- allocWords ngroups
96 ngroups <- _casm_ ``%r = getgroups(%0,(gid_t *)%1);'' ngroups words
100 return (map (extract arr) [0..(ngroups-1)])
104 extract (ByteArray _ barr#) (I# n#) =
105 case indexIntArray# barr# n# of
109 getEffectiveUserName :: IO String
110 getEffectiveUserName = do
111 str <- _ccall_ cuserid (``NULL''::Addr)
113 then syserr "getEffectiveUserName"
116 getProcessGroupID :: IO ProcessGroupID
117 getProcessGroupID = _ccall_ getpgrp
119 createProcessGroup :: ProcessID -> IO ProcessGroupID
120 createProcessGroup pid = do
121 pgid <- _ccall_ setpgid pid 0
124 else syserr "createProcessGroup"
126 joinProcessGroup :: ProcessGroupID -> IO ()
127 joinProcessGroup pgid =
128 nonzero_error (_ccall_ setpgid 0 pgid) "joinProcessGroupID"
130 setProcessGroupID :: ProcessID -> ProcessGroupID -> IO ()
131 setProcessGroupID pid pgid =
132 nonzero_error (_ccall_ setpgid pid pgid) "setProcessGroupID"
134 createSession :: IO ProcessGroupID
136 pgid <- _ccall_ setsid
139 else syserr "createSession"
141 type SystemID = ByteArray ()
143 systemName :: SystemID -> String
144 systemName sid = unsafePerformIO $ do
145 str <-_casm_ ``%r = ((struct utsname *)%0)->sysname;'' sid
148 nodeName :: SystemID -> String
149 nodeName sid = unsafePerformIO $ do
150 str <- _casm_ ``%r = ((struct utsname *)%0)->nodename;'' sid
153 release :: SystemID -> String
154 release sid = unsafePerformIO $ do
155 str <- _casm_ ``%r = ((struct utsname *)%0)->release;'' sid
158 version :: SystemID -> String
159 version sid = unsafePerformIO $ do
160 str <- _casm_ ``%r = ((struct utsname *)%0)->version;'' sid
163 machine :: SystemID -> String
164 machine sid = unsafePerformIO $ do
165 str <- _casm_ ``%r = ((struct utsname *)%0)->machine;'' sid
168 getSystemID :: IO SystemID
170 bytes <- allocChars (``sizeof(struct utsname)''::Int)
171 rc <- _casm_ ``%r = uname((struct utsname *)%0);'' bytes
174 else syserr "getSystemID"
176 epochTime :: IO EpochTime
178 secs <- _ccall_ time (``NULL''::Addr)
181 else syserr "epochTime"
183 -- All times in clock ticks (see getClockTick)
185 type ProcessTimes = (ClockTick, ByteArray ())
187 elapsedTime :: ProcessTimes -> ClockTick
188 elapsedTime (realtime, _) = realtime
190 userTime :: ProcessTimes -> ClockTick
191 userTime (_, times) = unsafePerformIO $
192 _casm_ ``%r = ((struct tms *)%0)->tms_utime;'' times
194 systemTime :: ProcessTimes -> ClockTick
195 systemTime (_, times) = unsafePerformIO $
196 _casm_ ``%r = ((struct tms *)%0)->tms_stime;'' times
198 childUserTime :: ProcessTimes -> ClockTick
199 childUserTime (_, times) = unsafePerformIO $
200 _casm_ ``%r = ((struct tms *)%0)->tms_cutime;'' times
202 childSystemTime :: ProcessTimes -> ClockTick
203 childSystemTime (_, times) = unsafePerformIO $
204 _casm_ ``%r = ((struct tms *)%0)->tms_cstime;'' times
206 getProcessTimes :: IO ProcessTimes
208 bytes <- allocChars (``sizeof(struct tms)''::Int)
209 elapsed <- _casm_ ``%r = times((struct tms *)%0);'' bytes
212 times <- freeze bytes
213 return (elapsed, times)
215 syserr "getProcessTimes"
217 #if !defined(cygwin32_TARGET_OS)
218 getControllingTerminalName :: IO FilePath
219 getControllingTerminalName = do
220 str <- _ccall_ ctermid (``NULL''::Addr)
222 then fail (IOError Nothing NoSuchThing "getControllingTerminalName: no controlling terminal")
226 getTerminalName :: Fd -> IO FilePath
227 getTerminalName fd = do
228 str <- _ccall_ ttyname fd
231 err <- try (queryTerminal fd)
232 either (\err -> syserr "getTerminalName")
233 (\succ -> if succ then fail (IOError Nothing NoSuchThing
234 "getTerminalName: no name")
235 else fail (IOError Nothing InappropriateType
236 "getTerminalName: not a terminal"))
240 queryTerminal :: Fd -> IO Bool
241 queryTerminal (FD# fd) = do
242 rc <- _ccall_ isatty fd
244 -1 -> syserr "queryTerminal"
248 data SysVar = ArgumentLimit
257 getSysVar :: SysVar -> IO Limit
260 ArgumentLimit -> sysconf ``_SC_ARG_MAX''
261 ChildLimit -> sysconf ``_SC_CHILD_MAX''
262 ClockTick -> sysconf ``_SC_CLK_TCK''
263 GroupLimit -> sysconf ``_SC_NGROUPS_MAX''
264 OpenFileLimit -> sysconf ``_SC_OPEN_MAX''
265 PosixVersion -> sysconf ``_SC_VERSION''
266 HasSavedIDs -> sysconf ``_SC_SAVED_IDS''
267 HasJobControl -> sysconf ``_SC_JOB_CONTROL''
270 sysconf :: Int -> IO Limit
272 rc <- _ccall_ sysconf n
275 else fail (IOError Nothing NoSuchThing
276 "getSysVar: no such system limit or option")