3a4d7e1997-09-03Per Hedbor /*
6208581997-09-03Per Hedbor  * $Id: proc.pike,v 1.2 1997/09/03 05:19:29 per Exp $
3a4d7e1997-09-03Per Hedbor  */ inherit "wizard"; constant name= "Status//Extended process status"; constant doc = "Shows detailed process status on Solaris 2.5 and 2.6."; constant more=1;
6208581997-09-03Per Hedbor void create() { if(!file_stat("/usr/proc/bin/")) throw("Only available under Solaris 2.4 and newer\n"); }
3a4d7e1997-09-03Per Hedbor string proc(string prog, int pid ) { if(!pid) pid=getpid(); object p = ((program)"privs")("Process status"); return popen("/usr/proc/bin/p"+prog+" "+pid); } string process_map(string in) { string q="<table>"; mapping map = ([]); foreach((in/"\n")[1..], string m) { string a,b; while(sscanf(m, "%s: %s", a,b)==2) m=a+":"+b; m=replace(m,"[ heap ]","Heap&nbsp(malloced&nbsp;memory)"); m=replace(m,"[ stack ]","Stack"); array row = (replace(m,"\t"," ")/" "-({""}))[1..]; row=replace(row, "read/exec", "read/exec/shared"); row=replace(row, "read/shared", "read/exec/shared"); row=replace(row, "read/exec/shared", "Shared"); row=replace(row, "read/write/shared", "Shared"); row=replace(row, "read/write/exec/shared", "Shared"); row=replace(row, "read/write", "Private"); row=replace(row, "read/write/exec", "Private"); if(sizeof(row)>1) map[row[1]] += (int)row[0]; } foreach(sort(indices(map)), string s) if(map[s]>1024) q += "<tr><td>"+s+"</td><td>"+sprintf("%.1f%s",map[s]/1024.0,"Mb")+"</td>"; else q += "<tr><td>"+s+"</td><td>"+sprintf("%d%s",map[s],"Kb")+"</td>"; return q+"</table>"; } string process_map2(string in) { string kbytes,resident,shared,priv; if(sscanf(((in/"\n")[-2]/" "-({""}))[2..]*" ", "%[^ ] %[^ ] %[^ ] %[^ ]",kbytes,resident,shared,priv)==4) return sprintf("%d Kbytes, %d Kb shared, %d Kb private, %d Kb resident", (int)kbytes,(int)shared,(int)priv,(int)resident); return "Failed to parse output from pmap."; } string format_proc_line(string in, int ipid) { string pre; int pid; sscanf(in, "%*s%d%*s", pid); sscanf(in,"%[ ]%s",pre,in); pre=replace(pre," "," |"); if(strlen(pre))pre=" "+pre[1..]; if(search(in,"/proc/")==-1) return (pre+ "<a href=/Actions/?action=proc.pike&pid="+pid+"&unique="+time()+">"+ (ipid==pid?"<b>":"")+ html_encode_string(in)+ (ipid==pid?"</b>":"")+ "</a>\n"); return ""; } mixed page_0(object id, object mc) { string map = proc("map -x",(int)id->variables->pid); if(sscanf(map, "%*sShared%*s") != 2) map = process_map(proc("map",(int)id->variables->pid)); else map = process_map2(map); string tree = Array.map(proc("tree -a",(int)id->variables->pid)/"\n",format_proc_line, (int)id->variables->pid||getpid())*""; return ("<font size=+1>Process Tree for "+(id->variables->pid||getpid())+"</font><pre>\n"+ tree+ "</pre><font size=+1>Misc status for "+(id->variables->pid||getpid()) +"</font><pre>Memory Usage: "+map+"\n\nCredentials: "+ ((proc("cred",id->variables->pid)/":")[1..]*":")+ "\nPwd: "+ ((proc("wdx",id->variables->pid)/":")[1..]*":")+ // "Stack: "+(proc("stack",id->variables->pid)/":")[1..]*":"+ "</pre>"); } mixed handle(object id) { return wizard_for(id,0); }