
Hello (Newbie question ahead :) I'm trying to write a program which will build a tree (here represented as a Map) of unix processes. The tree should be built by reading the process information stored in /proc/PID/status. There is also another Map which will be used for faster insertions on the process tree, which I'd like to handle as my program state. So far I have the functions to get a list of entries from /proc, filter the ones that represent processes and get the information from their status file. Now I need an "insertProc" function, which should get the information for a given process ID, update the state and return that information. This is where I think I need StateT, but I couldn't find out how to use it (never used StateT before...). This is what I have so far:
type Pid = FilePath type Uid = String
type PsData = Map String Uid type PsChildren = Map Pid PsInfo
data PsInfo = PsInfo PsData PsChildren type PsMap = Map Pid PsInfo type PsTree = Map Pid PsInfo
parent :: PsData -> Pid parent psData = fromJust $ Map.lookup "PPid" psData
getProcInfo :: PsData -> String -> IO PsData getProcInfo psData line = do case matchRegex (mkRegex "^([a-z]+):[[:space:]]+(.*)$") line of Nothing -> return (psData) Just [key, value] -> return (Map.insert key value psData)
procInfo :: Pid -> IO PsInfo procInfo pid = do procData <- readFile $ "/proc/" ++ pid ++ "/status" psData <- foldM getProcInfo Map.empty (lines procData) let [rUid, eUid, _] = words $ fromJust (Map.lookup "Uid" psData) let [rGid, eGid, _] = words $ fromJust (Map.lookup "Gid" psData) let uids = Map.fromList [("RUid", rUid), ("EUid", eUid), ("RGid", rGid), ("EGid", eGid)] let psData' = Map.union psData uids return (PsInfo psData' Map.empty)
I tried this for insertProc, but it obviously doesn't work... what would be the correct way to do this?
insertProc :: Pid -> StateT PsMap IO PsInfo insertProc pid = do proc <- procInfo pid -- XXX this is obviously wrong... psMap <- get put (Map.insert pid proc psMap) return (proc)
A second question: is it possible to make getProcInfo's type to be PsData -> String -> PsData and use some operation similar to lift so that it can be used with foldM, instead of making its return type to be IO PsData explicitely? Thanks in advance, Andre