/**linux/fs/proc/array.c**Copyright(C)1992byLinusTorvalds*basedonideasbyDarrenSenn**Fixes:*Michael.K.Johnson:stat,statmextensions.*<johnsonm@stolaf.
edu>**PaulineMiddelink:Madecmdline,envlineonlybreakat'\0's,to*makesureSETPROCTITLEworks.Alsoremoved*bad'!'whichforcedaddressrecalculationfor*EVERYch
aracteronthecurrentpage.*<middelin@polyware.iaf.nl>**DannyterHaar:addedcpuinfo*<dth@cistron.nl>**AlessandroRubini:profileextension.*<rubini@ipvvis.u
nipv.it>**JeffTranter:addedBogoMipsfieldtocpuinfo*<JeffTranter@Mitel.COM>**BrunoHaible:remove4Klimitforthemapsfile*<haible@ma2s2.mathematik.uni-karl
sruhe.de>**YvesArrouye:removeremovaloftrailingspacesingetarray.*<Yves.Arrouye@marin.fdn.fr>**JeromeForissier:addedper-CPUtimeinformationto/proc/stat
*and/proc/<pid>/cpuextension*<forissier@isia.cma.fr>*-Incorporationandnon-SMPsafeoperation*offorissierpatchin2.1.78by*HansMarcus<crowbar@concepts.nl
>**aeb@cwi.nl:/proc/partitions***AlanCox:securityfixes.*<Alan.Cox@linux.org>**GerhardWichert:addedBIGMEMsupport*SiemensAG<Gerhard.Wichert@pdb.siemen
s.de>*/#include<linux/types.h>#include<linux/errno.h>#include<linux/sched.h>#include<linux/kernel.h>#include<linux/kernelstat.h>#include<linux/tty.h
>#include<linux/user.h>#include<linux/a.out.h>#include<linux/string.h>#include<linux/mman.h>#include<linux/procfs.h>#include<linux/ioport.h>#include
<linux/config.h>#include<linux/mm.h>#include<linux/pagemap.h>#include<linux/swap.h>#include<linux/slab.h>#include<linux/smp.h>#include<linux/signal.
h>#include<asm/uaccess.h>#include<asm/pgtable.h>#include<asm/io.h>#defineLOADINT(x)((x)>>FSHIFT)#defineLOADFRAC(x)LOADINT(((x)&(FIXED1-1))*100)#ifde
fCONFIGDEBUGMALLOCintgetmalloc(char*buffer);#endifstaticintopenkcore(structinode*inode,structfile*filp){returncapable(CAPSYSRAWIO)?0:-EPERM;}statics
sizetreadcore(structfile*file,char*buf,sizetcount,lofft*ppos){unsignedlongp=*ppos,memsize;ssizetread;ssizetcount1;char*pnt;structuserdump;#ifdefined
(i386)||defined(mc68000)#defineFIRSTMAPPEDPAGESIZE/*wedon'thavepage0mappedonx86..*/#else#defineFIRSTMAPPED0#endifmemset(&dump,0,sizeof(structuser));
dump.magic=CMAGIC;dump.udsize=maxmapnr;#ifdefined(i386)dump.startcode=PAGEOFFSET;#endif#ifdefalphadump.startdata=PAGEOFFSET;#endifmemsize=(maxmapnr+
1)<<PAGESHIFT;if(p>=memsize)return0;if(count>memsize-p)count=memsize-p;read=0;if(p<sizeof(structuser)&&count>0){count1=count;if(p+count1>sizeof(stru
ctuser))count1=sizeof(structuser)-p;pnt=(char*)&dump+p;copytouser(buf,(void*)pnt,count1);buf+=count1;p+=count1;count-=count1;read+=count1;}if(count>
0&&p<PAGESIZE+FIRSTMAPPED){count1=PAGESIZE+FIRSTMAPPED-p;if(count1>count)count1=count;clearuser(buf,count1);buf+=count1;p+=count1;count-=count1;read
+=count1;}if(count>0){copytouser(buf,(void*)(PAGEOFFSET+p-PAGESIZE),count);read+=count;}*ppos+=read;returnread;}staticstructfileoperationsprockcoreo
perations={NULL,/*lseek*/readcore,NULL,/*write*/NULL,/*readdir*/NULL,/*poll*/NULL,/*ioctl*/NULL,/*mmap*/openkcore};structinodeoperationsprockcoreino
deoperations={&prockcoreoperations,};/**Thisfunctionaccessesprofilinginformation.Thereturneddatais*binary:thesamplingstepandtheactualcontentsofthepr
ofile*buffer.Useoftheprogramreadprofileisrecommendedinorderto*getmeaningfulinfooutofthesedata.*/staticssizetreadprofile(structfile*file,char*buf,siz
etcount,lofft*ppos){unsignedlongp=*ppos;ssizetread;char*pnt;unsignedintsamplestep=1<<profshift;if(p>=(proflen+1)*sizeof(unsignedint))return0;if(coun
t>(proflen+1)*sizeof(unsignedint)-p)count=(proflen+1)*sizeof(unsignedint)-p;read=0;while(p<sizeof(unsignedint)&&count>0){putuser(*((char*)(&samplest
ep)+p),buf);buf++;p++;count--;read++;}pnt=(char*)profbuffer+p-sizeof(unsignedint);copytouser(buf,(void*)pnt,count);read+=count;*ppos+=read;returnrea
d;}/**Writingto/proc/profileresetsthecounters**Writinga'profilingmultiplier'valueintoitalsore-setstheprofiling*interruptfrequency,onarchitecturestha
tsupportthis.*/staticssizetwriteprofile(structfile*file,constchar*buf,sizetcount,lofft*ppos){#ifdefSMPexternintsetupprofilingtimer(unsignedintmultip
lier);if(count==sizeof(int)){unsignedintmultiplier;if(copyfromuser(&multiplier,buf,sizeof(int)))return-EFAULT;if(setupprofilingtimer(multiplier))ret
urn-EINVAL;}#endifmemset(profbuffer,0,proflen*sizeof(*profbuffer));returncount;}staticstructfileoperationsprocprofileoperations={NULL,/*lseek*/readp
rofile,writeprofile,};structinodeoperationsprocprofileinodeoperations={&procprofileoperations,};staticintgetloadavg(char*buffer){inta,b,c;a=avenrun[
0]+(FIXED1/200);b=avenrun[1]+(FIXED1/200);c=avenrun[2]+(FIXED1/200);returnsprintf(buffer,"%d.%02d%d.%02d%d.%02d%d/%d%d\n",LOADINT(a),LOADFRAC(a),LOA
DINT(b),LOADFRAC(b),LOADINT(c),LOADFRAC(c),nrrunning,nrtasks,lastpid);}staticintgetkstat(char*buffer){inti,len;unsignedsum=0;externunsignedlongtotal
forks;unsignedlongticks;ticks=jiffies*smpnumcpus;#ifndefCONFIGARCHS390for(i=0;i<NRIRQS;i++)sum+=kstatirqs(i);#endif#ifdefSMPlen=sprintf(buffer,"cpu%
u%u%u%lu\n",kstat.cpuuser,kstat.cpunice,kstat.cpusystem,jiffies*smpnumcpus-(kstat.cpuuser+kstat.cpunice+kstat.cpusystem));for(i=0;i<smpnumcpus;i++)l
en+=sprintf(buffer+len,"cpu%d%u%u%u%lu\n",i,kstat.percpuuser[cpulogicalmap(i)],kstat.percpunice[cpulogicalmap(i)],kstat.percpusystem[cpulogicalmap(i
)],jiffies-(kstat.percpuuser[cpulogicalmap(i)]\+kstat.percpunice[cpulogicalmap(i)]\+kstat.percpusystem[cpulogicalmap(i)]));len+=sprintf(buffer+len,"
disk%u%u%u%u\n""diskrio%u%u%u%u\n""diskwio%u%u%u%u\n""diskrblk%u%u%u%u\n""diskwblk%u%u%u%u\n""page%u%u\n"#ifdefCONFIGARCHS390"swap%u%u\n""intr10",#e
lse"swap%u%u\n""intr%u",#endif#elselen=sprintf(buffer,"cpu%u%u%u%lu\n""disk%u%u%u%u\n""diskrio%u%u%u%u\n""diskwio%u%u%u%u\n""diskrblk%u%u%u%u\n""dis
kwblk%u%u%u%u\n""page%u%u\n"#ifdefCONFIGARCHS390"swap%u%u\n""intr10",#else"swap%u%u\n""intr%u",#endifkstat.cpuuser,kstat.cpunice,kstat.cpusystem,tic
ks-(kstat.cpuuser+kstat.cpunice+kstat.cpusystem),#endifkstat.dkdrive[0],kstat.dkdrive[1],kstat.dkdrive[2],kstat.dkdrive[3],kstat.dkdriverio[0],kstat
.dkdriverio[1],kstat.dkdriverio[2],kstat.dkdriverio[3],kstat.dkdrivewio[0],kstat.dkdrivewio[1],kstat.dkdrivewio[2],kstat.dkdrivewio[3],kstat.dkdrive
rblk[0],kstat.dkdriverblk[1],kstat.dkdriverblk[2],kstat.dkdriverblk[3],kstat.dkdrivewblk[0],kstat.dkdrivewblk[1],kstat.dkdrivewblk[2],kstat.dkdrivew
blk[3],kstat.pgpgin,kstat.pgpgout,kstat.pswpin,#ifdefCONFIGARCHS390kstat.pswpout);#elsekstat.pswpout,sum);for(i=0;i<NRIRQS;i++)len+=sprintf(buffer+l
en,"%u",kstatirqs(i));#endiflen+=sprintf(buffer+len,"\nctxt%u\n""btime%lu\n""processes%lu\n",kstat.contextswtch,xtime.tvsec-jiffies/HZ,totalforks);r
eturnlen;}staticintgetuptime(char*buffer){unsignedlonguptime;unsignedlongidle;uptime=jiffies;idle=task[0]->times.tmsutime+task[0]->times.tmsstime;/*
Theformulaforthefractionpartsreallyis((t*100)/HZ)%100,butthatwouldoverflowabouteveryfivedaysatHZ==100.Thereforetheidentitya=(a/b)*b+a%bisusedsothati
tiscalculatedas(((t/HZ)*100)+((t%HZ)*100)/HZ)%100.Thepartinfrontofthe'+'alwaysevaluatesas0(mod100).Alldivisionsintheaboveformulasaretruncating.ForHZ
beingapowerof10,thecalculationssimplifytotheversioninthe#elsepart(iftheprintfformatisadaptedtothesamenumberofdigitsaszeroesinHZ.*/#ifHZ!=100returnsp
rintf(buffer,"%lu.%02lu%lu.%02lu\n",uptime/HZ,(((uptime%HZ)*100)/HZ)%100,idle/HZ,(((idle%HZ)*100)/HZ)%100);#elsereturnsprintf(buffer,"%lu.%02lu%lu.%
02lu\n",uptime/HZ,uptime%HZ,idle/HZ,idle%HZ);#endif}staticintgetmeminfo(char*buffer){structsysinfoi;intlen;simeminfo(&i);siswapinfo(&i);len=sprintf(
buffer,"total:used:free:shared:buffers:cached:\n""Mem:%8lu%8lu%8lu%8lu%8lu%8lu\n""Swap:%8lu%8lu%8lu\n",i.totalram,i.totalram-i.freeram,i.freeram,i.s
haredram,i.bufferram,pagecachesize*PAGESIZE,i.totalswap,i.totalswap-i.freeswap,i.freeswap);/**Taggedformat,foreasygreppingandexpansion.Theabovewillg
oaway*eventually,oncethetoolshavebeenupdated.*/returnlen+sprintf(buffer+len,"MemTotal:%8lukB\n""MemFree:%8lukB\n""MemShared:%8lukB\n""Buffers:%8lukB
\n""Cached:%8lukB\n""BigTotal:%8lukB\n""BigFree:%8lukB\n""SwapTotal:%8lukB\n""SwapFree:%8lukB\n",i.totalram>>10,i.freeram>>10,i.sharedram>>10,i.buff
erram>>10,pagecachesize<<(PAGESHIFT-10),i.totalbig>>10,i.freebig>>10,i.totalswap>>10,i.freeswap>>10);}staticintgetversion(char*buffer){externchar*li
nuxbanner;strcpy(buffer,linuxbanner);returnstrlen(buffer);}staticintgetcmdline(char*buffer){externcharsavedcommandline[];returnsprintf(buffer,"%s\n"
,savedcommandline);}staticunsignedlonggetphysaddr(structtaskstruct*p,unsignedlongptr){pgdt*pagedir;pmdt*pagemiddle;ptetpte;if(!p||!p->mm||ptr>=TASKS
IZE)return0;/*CheckforNULLpgd..shouldn'thappen!*/if(!p->mm->pgd){printk("getphysaddr:pid%dhasNULLpgd!\n",p->pid);return0;}pagedir=pgdoffset(p->mm,pt
r);if(pgdnone(*pagedir))return0;if(pgdbad(*pagedir)){printk("badpagedirectoryentry%08lx\n",pgdval(*pagedir));pgdclear(pagedir);return0;}pagemiddle=p
mdoffset(pagedir,ptr);if(pmdnone(*pagemiddle))return0;if(pmdbad(*pagemiddle)){printk("badpagemiddleentry%08lx\n",pmdval(*pagemiddle));pmdclear(pagem
iddle);return0;}pte=*pteoffset(pagemiddle,ptr);if(!ptepresent(pte))return0;returnptepage(pte)+(ptr&~PAGEMASK);}#include<linux/bigmem.h>staticintgeta
rray(structtaskstruct*p,unsignedlongstart,unsignedlongend,char*buffer){unsignedlongaddr;intsize=0,result=0;charc;if(start>=end)returnresult;for(;;){
addr=getphysaddr(p,start);if(!addr)returnresult;addr=kmap(addr,KMREAD);do{c=*(char*)addr;if(!c)result=size;if(size<PAGESIZE)buffer[size++]=c;else{ku
nmap(addr,KMREAD);returnresult;}addr++;start++;if(!c&&start>=end){kunmap(addr,KMREAD);returnresult;}}while(addr&~PAGEMASK);kunmap(addr-1,KMREAD);}re
turnresult;}staticintgetenv(intpid,char*buffer){structtaskstruct*p;readlock(&tasklistlock);p=findtaskbypid(pid);readunlock(&tasklistlock);/*FIXME!!T
hisshouldbedoneafterthelastuse*/if(!p||!p->mm)return0;returngetarray(p,p->mm->envstart,p->mm->envend,buffer);}staticintgetarg(intpid,char*buffer){st
ructtaskstruct*p;readlock(&tasklistlock);p=findtaskbypid(pid);readunlock(&tasklistlock);/*FIXME!!Thisshouldbedoneafterthelastuse*/if(!p||!p->mm)retu
rn0;returngetarray(p,p->mm->argstart,p->mm->argend,buffer);}/**Thesebracketthesleepingfunctions..*/externvoidschedulingfunctionsstarthere(void);exte
rnvoidschedulingfunctionsendhere(void);#definefirstsched((unsignedlong)schedulingfunctionsstarthere)#definelastsched((unsignedlong)schedulingfunctio
nsendhere)staticunsignedlonggetwchan(structtaskstruct*p){if(!p||p==current||p->state==TASKRUNNING)return0;#ifdefined(i386){unsignedlongebp,esp,eip;u
nsignedlongstackpage;intcount=0;stackpage=(unsignedlong)p;esp=p->tss.esp;if(!stackpage||esp<stackpage||esp>=8188+stackpage)return0;/*include/asm-i38
6/system.h:switchto()pushesebplast.*/ebp=*(unsignedlong*)esp;do{if(ebp<stackpage||ebp>=8188+stackpage)return0;eip=*(unsignedlong*)(ebp+4);if(eip<fir
stsched||eip>=lastsched)returneip;ebp=*(unsignedlong*)ebp;}while(count++<16);}#elifdefined(alpha)/**Thisonedependsontheframesizeofschedule().Doa*"di
sassschedule"ingdbtofindtheframesize.Also,the*codeassumesthatsleepon()followsimmediatelyafter*interruptiblesleepon()andthataddtimer()follows*immedia
telyafterinterruptiblesleep().Ugly,isn'tit?*Maybeaddingawchanfieldtotaskstructwouldbebetter,*afterall...*/{unsignedlongscheduleframe;unsignedlongpc;
pc=threadsavedpc(&p->tss);if(pc>=firstsched&&pc<lastsched){scheduleframe=((unsignedlong*)p->tss.ksp)[6];return((unsignedlong*)scheduleframe)[12];}re
turnpc;}#elifdefined(mips)/**ThesamecommentasontheAlphaapplieshere,too...*/{unsignedlongscheduleframe;unsignedlongpc;pc=threadsavedpc(&p->tss);if(pc
>=(unsignedlong)interruptiblesleepon&&pc<(unsignedlong)addtimer){scheduleframe=((unsignedlong*)(long)p->tss.reg30)[16];return(unsignedlong)((unsigne
dlong*)scheduleframe)[11];}returnpc;}#elifdefined(mc68000){unsignedlongfp,pc;unsignedlongstackpage;intcount=0;stackpage=(unsignedlong)p;fp=((structs
witchstack*)p->tss.ksp)->a6;do{if(fp<stackpage+sizeof(structtaskstruct)||fp>=8184+stackpage)return0;pc=((unsignedlong*)fp)[1];/*FIXME:Thisdependsont
heorderofthesefunctions.*/if(pc<firstsched||pc>=lastsched)returnpc;fp=*(unsignedlong*)fp;}while(count++<16);}#elifdefined(powerpc){unsignedlongip,sp
;unsignedlongstackpage=(unsignedlong)p;intcount=0;sp=p->tss.ksp;do{sp=*(unsignedlong*)sp;if(sp<stackpage||sp>=stackpage+8188)return0;if(count>0){ip=
*(unsignedlong*)(sp+4);if(ip<firstsched||ip>=lastsched)returnip;}}while(count++<16);}#elifdefined(arm){unsignedlongfp,lr;unsignedlongstackpage;intco
unt=0;stackpage=4096+(unsignedlong)p;fp=getcssfp(&p->tss);do{if(fp<stackpage||fp>4092+stackpage)return0;lr=pcpointer(((unsignedlong*)fp)[-1]);if(lr<
firstsched||lr>lastsched)returnlr;fp=*(unsignedlong*)(fp-12);}while(count++<16);}#elifdefined(sparc){unsignedlongpc,fp,bias=0;unsignedlongtaskbase=(
unsignedlong)p;structregwindow*rw;intcount=0;#ifdefsparcv9bias=STACKBIAS;#endiffp=p->tss.ksp+bias;do{/*Bogusframepointer?*/if(fp<(taskbase+sizeof(st
ructtaskstruct))||fp>=(taskbase+(2*PAGESIZE)))break;rw=(structregwindow*)fp;pc=rw->ins[7];if(pc<firstsched||pc>=lastsched)returnpc;fp=rw->ins[6]+bia
s;}while(++count<16);}#elifdefined(s390){unsignedlongksp,backchain,ip;unsignedlongstackpage;intcount=0;stackpage=(unsignedlong)p;ksp=p->tss.ksp;if(!
stackpage||ksp<stackpage||ksp>=8188+stackpage)return0;backchain=(*(unsignedlong*)ksp)&0x7fffffff;do{if(backchain<stackpage||backchain>=8188+stackpag
e)return0;ip=(*(unsignedlong*)(backchain+56))&0x7fffffff;if(ip<firstsched||ip>=lastsched)returnip;backchain=(*(unsignedlong*)backchain)&0x7fffffff;}
while(count++<16);}#endifreturn0;}#ifdefined(i386)#defineKSTKEIP(tsk)(((unsignedlong*)(4096+(unsignedlong)(tsk)))[1019])#defineKSTKESP(tsk)(((unsign
edlong*)(4096+(unsignedlong)(tsk)))[1022])#elifdefined(alpha)/**Seearch/alpha/kernel/ptrace.cfordetails.*/#definePTREG(reg)(PAGESIZE-sizeof(structpt
regs)\+(long)&((structptregs*)0)->reg)#defineKSTKEIP(tsk)\(*(unsignedlong*)(PTREG(pc)+PAGESIZE+(unsignedlong)(tsk)))#defineKSTKESP(tsk)((tsk)==curre
nt?rdusp():(tsk)->tss.usp)#elifdefined(arm)#defineKSTKEIP(tsk)(((unsignedlong*)(4096+(unsignedlong)(tsk)))[1022])#defineKSTKESP(tsk)(((unsignedlong*
)(4096+(unsignedlong)(tsk)))[1020])#elifdefined(mc68000)#defineKSTKEIP(tsk)\({\unsignedlongeip=0;\if((tsk)->tss.esp0>PAGESIZE&&\MAPNR((tsk)->tss.esp
0)<maxmapnr)\eip=((structptregs*)(tsk)->tss.esp0)->pc;\eip;})#defineKSTKESP(tsk)((tsk)==current?rdusp():(tsk)->tss.usp)#elifdefined(powerpc)#defineK
STKEIP(tsk)((tsk)->tss.regs->nip)#defineKSTKESP(tsk)((tsk)->tss.regs->gpr[1])#elifdefined(sparcv9)#defineKSTKEIP(tsk)((tsk)->tss.kregs->tpc)#defineK
STKESP(tsk)((tsk)->tss.kregs->uregs[UREGFP])#elifdefined(sparc)#defineKSTKEIP(tsk)((tsk)->tss.kregs->pc)#defineKSTKESP(tsk)((tsk)->tss.kregs->uregs[
UREGFP])#elifdefined(mips)#definePTREG(reg)((long)&((structptregs*)0)->reg\-sizeof(structptregs))#defineKSTKTOS(tsk)((unsignedlong)(tsk)+KERNELSTACK
SIZE-32)#defineKSTKEIP(tsk)(*(unsignedlong*)(KSTKTOS(tsk)+PTREG(cp0epc)))#defineKSTKESP(tsk)(*(unsignedlong*)(KSTKTOS(tsk)+PTREG(regs[29])))#elifdef
ined(s390)#defineKSTKEIP(tsk)((tsk)->tss.regs->psw.addr)#defineKSTKESP(tsk)((tsk)->tss.ksp)#endif/*Gccoptimizesaway"strlen(x)"forconstantx*/#defineA
DDBUF(buffer,string)\do{memcpy(buffer,string,strlen(string));\buffer+=strlen(string);}while(0)staticinlinechar*taskname(structtaskstruct*p,char*buf)
{inti;char*name;ADDBUF(buf,"Name:\t");name=p->comm;i=sizeof(p->comm);do{unsignedcharc=*name;name++;i--;*buf=c;if(!c)break;if(c=='\\'){buf[1]=c;buf+=
2;continue;}if(c=='\n'){buf[0]='\\';buf[1]='n';buf+=2;continue;}buf++;}while(i);*buf='\n';returnbuf+1;}/**Thetaskstatearrayisastrange"bitmap"of*reas
onstosleep.Thus"running"iszero,and*youcantestforcombinationsofotherswith*simplebittests.*/staticconstchar*taskstatearray[]={"R(running)",/*0*/"S(sle
eping)",/*1*/"D(disksleep)",/*2*/"Z(zombie)",/*4*/"T(stopped)",/*8*/"W(paging)"/*16*/};staticinlineconstchar*gettaskstate(structtaskstruct*tsk){unsi
gnedintstate=tsk->state&(TASKRUNNING|TASKINTERRUPTIBLE|TASKUNINTERRUPTIBLE|TASKZOMBIE|TASKSTOPPED|TASKSWAPPING);constchar**p=&taskstatearray[0];whil
e(state){p++;state>>=1;}return*p;}staticinlinechar*taskstate(structtaskstruct*p,char*buffer){intg;buffer+=sprintf(buffer,"State:\t%s\n""Pid:\t%d\n""
PPid:\t%d\n""Uid:\t%d\t%d\t%d\t%d\n""Gid:\t%d\t%d\t%d\t%d\n""Groups:\t",gettaskstate(p),p->pid,p->ppptr->pid,p->uid,p->euid,p->suid,p->fsuid,p->gid,
p->egid,p->sgid,p->fsgid);for(g=0;g<p->ngroups;g++)buffer+=sprintf(buffer,"%d",p->groups[g]);buffer+=sprintf(buffer,"\n");returnbuffer;}staticinline
char*taskmem(structtaskstruct*p,char*buffer){structmmstruct*mm=p->mm;if(mm&&mm!=&initmm){structvmareastruct*vma=mm->mmap;unsignedlongdata=0,stack=0;
unsignedlongexec=0,lib=0;for(vma=mm->mmap;vma;vma=vma->vmnext){unsignedlonglen=(vma->vmend-vma->vmstart)>>10;if(!vma->vmfile){data+=len;if(vma->vmfl
ags&VMGROWSDOWN)stack+=len;continue;}if(vma->vmflags&VMWRITE)continue;if(vma->vmflags&VMEXEC){exec+=len;if(vma->vmflags&VMEXECUTABLE)continue;lib+=l
en;}}buffer+=sprintf(buffer,"VmSize:\t%8lukB\n""VmLck:\t%8lukB\n""VmRSS:\t%8lukB\n""VmData:\t%8lukB\n""VmStk:\t%8lukB\n""VmExe:\t%8lukB\n""VmLib:\t%
8lukB\n",mm->totalvm<<(PAGESHIFT-10),mm->lockedvm<<(PAGESHIFT-10),mm->rss<<(PAGESHIFT-10),data-stack,stack,exec-lib,lib);}returnbuffer;}staticvoidco
llectsigignsigcatch(structtaskstruct*p,sigsett*ign,sigsett*catch){structksigaction*k;inti;sigemptyset(ign);sigemptyset(catch);if(p->sig){k=p->sig->a
ction;for(i=1;i<=NSIG;++i,++k){if(k->sa.sahandler==SIGIGN)sigaddset(ign,i);elseif(k->sa.sahandler!=SIGDFL)sigaddset(catch,i);}}}staticinlinechar*tas
ksig(structtaskstruct*p,char*buffer){sigsettign,catch;buffer+=sprintf(buffer,"SigPnd:\t");buffer=rendersigsett(&p->signal,buffer);*buffer++='\n';buf
fer+=sprintf(buffer,"SigBlk:\t");buffer=rendersigsett(&p->blocked,buffer);*buffer++='\n';collectsigignsigcatch(p,&ign,&catch);buffer+=sprintf(buffer
,"SigIgn:\t");buffer=rendersigsett(&ign,buffer);*buffer++='\n';buffer+=sprintf(buffer,"SigCgt:\t");/*Linux2.0uses"SigCgt"*/buffer=rendersigsett(&cat
ch,buffer);*buffer++='\n';returnbuffer;}externinlinechar*taskcap(structtaskstruct*p,char*buffer){returnbuffer+sprintf(buffer,"CapInh:\t%016x\n""CapP
rm:\t%016x\n""CapEff:\t%016x\n",capt(p->capinheritable),capt(p->cappermitted),capt(p->capeffective));}staticintgetstatus(intpid,char*buffer){char*or
ig=buffer;structtaskstruct*tsk;readlock(&tasklistlock);tsk=findtaskbypid(pid);readunlock(&tasklistlock);/*FIXME!!Thisshouldbedoneafterthelastuse*/if
(!tsk)return0;buffer=taskname(tsk,buffer);buffer=taskstate(tsk,buffer);buffer=taskmem(tsk,buffer);buffer=tasksig(tsk,buffer);buffer=taskcap(tsk,buff
er);#ifs390buffer=taskshowregs(tsk,buffer);#endifreturnbuffer-orig;}staticintgetstat(intpid,char*buffer){structtaskstruct*tsk;unsignedlongvsize,eip,
esp,wchan;longpriority,nice;intttypgrp;sigsettsigign,sigcatch;charstate;readlock(&tasklistlock);tsk=findtaskbypid(pid);if(!tsk){readunlock(&tasklist
lock);return0;}state=*gettaskstate(tsk);vsize=eip=esp=0;if(tsk->mm&&tsk->mm!=&initmm){structvmareastruct*vma=tsk->mm->mmap;while(vma){vsize+=vma->vm
end-vma->vmstart;vma=vma->vmnext;}if((current->fsuid==tsk->euid&&tsk->dumpable&&capissubset(tsk->cappermitted,current->cappermitted))||capable(CAPDA
COVERRIDE)){eip=KSTKEIP(tsk);esp=KSTKESP(tsk);}}readunlock(&tasklistlock);/*FIXME!!Thisshouldbedoneafterthelastuse*/wchan=getwchan(tsk);collectsigig
nsigcatch(tsk,&sigign,&sigcatch);if(tsk->tty)ttypgrp=tsk->tty->pgrp;elsettypgrp=-1;/*scalepriorityandnicevaluesfromtimeslicesto-20..20*//*tomakeitlo
oklikea"normal"Unixpriority/nicevalue*/priority=tsk->counter;priority=20-(priority*10+DEFPRIORITY/2)/DEFPRIORITY;nice=tsk->priority;nice=20-(nice*20
+DEFPRIORITY/2)/DEFPRIORITY;returnsprintf(buffer,"%d(%s)%c%d%d%d%d%d%lu%lu\%lu%lu%lu%lu%lu%ld%ld%ld%ld%ld%ld%lu%lu%ld%lu%lu%lu%lu%lu\%lu%lu%lu%lu%lu
%lu%lu%lu%d%d\n",pid,tsk->comm,state,tsk->ppptr->pid,tsk->pgrp,tsk->session,tsk->tty?kdevttonr(tsk->tty->device):0,ttypgrp,tsk->flags,tsk->minflt,ts
k->cminflt,tsk->majflt,tsk->cmajflt,tsk->times.tmsutime,tsk->times.tmsstime,tsk->times.tmscutime,tsk->times.tmscstime,priority,nice,0UL/*removed*/,t
sk->itrealvalue,tsk->starttime,vsize,tsk->mm?tsk->mm->rss:0,/*youmightwanttoshiftthisleft3*/tsk->rlim?tsk->rlim[RLIMITRSS].rlimcur:0,tsk->mm?tsk->mm
->startcode:0,tsk->mm?tsk->mm->endcode:0,tsk->mm?tsk->mm->startstack:0,esp,eip,/*Thesignalinformationhereisobsolete.*ItmustbedecimalforLinux2.0compa
tibility.*Use/proc/#/statusforreal-timesignals.*/tsk->signal.sig[0]&0x7fffffffUL,tsk->blocked.sig[0]&0x7fffffffUL,sigign.sig[0]&0x7fffffffUL,sigcatc
h.sig[0]&0x7fffffffUL,wchan,tsk->nswap,tsk->cnswap,tsk->exitsignal,tsk->processor);}staticinlinevoidstatmpterange(pmdt*pmd,unsignedlongaddress,unsig
nedlongsize,int*pages,int*shared,int*dirty,int*total){ptet*pte;unsignedlongend;if(pmdnone(*pmd))return;if(pmdbad(*pmd)){printk("statmpterange:badpmd
(%08lx)\n",pmdval(*pmd));pmdclear(pmd);return;}pte=pteoffset(pmd,address);address&=~PMDMASK;end=address+size;if(end>PMDSIZE)end=PMDSIZE;do{ptetpage=
*pte;address+=PAGESIZE;pte++;if(ptenone(page))continue;++*total;if(!ptepresent(page))continue;++*pages;if(ptedirty(page))++*dirty;if(MAPNR(ptepage(p
age))>=maxmapnr)continue;if(atomicread(&memmap[MAPNR(ptepage(page))].count)>1)++*shared;}while(address<end);}staticinlinevoidstatmpmdrange(pgdt*pgd,
unsignedlongaddress,unsignedlongsize,int*pages,int*shared,int*dirty,int*total){pmdt*pmd;unsignedlongend;if(pgdnone(*pgd))return;if(pgdbad(*pgd)){pri
ntk("statmpmdrange:badpgd(%08lx)\n",pgdval(*pgd));pgdclear(pgd);return;}pmd=pmdoffset(pgd,address);address&=~PGDIRMASK;end=address+size;if(end>PGDIR
SIZE)end=PGDIRSIZE;do{statmpterange(pmd,address,end-address,pages,shared,dirty,total);address=(address+PMDSIZE)&PMDMASK;pmd++;}while(address<end);}s
taticvoidstatmpgdrange(pgdt*pgd,unsignedlongaddress,unsignedlongend,int*pages,int*shared,int*dirty,int*total){while(address<end){statmpmdrange(pgd,a
ddress,end-address,pages,shared,dirty,total);address=(address+PGDIRSIZE)&PGDIRMASK;pgd++;}}staticintgetstatm(intpid,char*buffer){structtaskstruct*ts
k;intsize=0,resident=0,share=0,trs=0,lrs=0,drs=0,dt=0;readlock(&tasklistlock);tsk=findtaskbypid(pid);readunlock(&tasklistlock);/*FIXME!!Thisshouldbe
doneafterthelastuse*/if(!tsk)return0;if(tsk->mm&&tsk->mm!=&initmm){structvmareastruct*vma=tsk->mm->mmap;while(vma){pgdt*pgd=pgdoffset(tsk->mm,vma->v
mstart);intpages=0,shared=0,dirty=0,total=0;statmpgdrange(pgd,vma->vmstart,vma->vmend,&pages,&shared,&dirty,&total);resident+=pages;share+=shared;dt
+=dirty;size+=total;if(vma->vmflags&VMEXECUTABLE)trs+=pages;/*text*/elseif(vma->vmflags&VMGROWSDOWN)drs+=pages;/*stack*/elseif(vma->vmend>0x60000000
)lrs+=pages;/*library*/elsedrs+=pages;vma=vma->vmnext;}}returnsprintf(buffer,"%d%d%d%d%d%d%d\n",size,resident,share,trs,lrs,drs,dt);}/**Thewaywesupp
ortsyntheticfiles>4K*-withoutstoringtheircontentsinsomebufferand*-withoutwalkingthroughtheentiresyntheticfileuntilwereachthe*positionoftherequestedd
ata*istocleverlyencodethecurrentpositioninthefile'sfposfield.*Thereisnorequirementthataread()callwhichreturns`count'bytes*ofdataincreasesfposbyexact
ly`count'.**ThisideaisLinus'one.Brunoimplementedit.*//**Forthe/proc/<pid>/mapsfile,weusefixedlengthrecords,eachcontaining*asingleline.*/#defineMAPSL
INELENGTH4096#defineMAPSLINESHIFT12/**fpos=(numberofthevmainthetask->mm->mmaplist)*MAPSLINELENGTH*+(indexintotheline)*//*forsystemswithsizeof(void*)
==4:*/#defineMAPSLINEFORMAT4"%08lx-%08lx%s%08lx%s%lu"#defineMAPSLINEMAX449/*sumof8181418151101*//*forsystemswithsizeof(void*)==8:*/#defineMAPSLINEFO
RMAT8"%016lx-%016lx%s%016lx%s%lu"#defineMAPSLINEMAX873/*sumof1611614116151101*/#defineMAPSLINEMAXMAPSLINEMAX8staticssizetreadmaps(intpid,structfile*
file,char*buf,sizetcount,lofft*ppos){structtaskstruct*p;structvmareastruct*map,*next;char*destptr=buf,*buffer;lofftlineno;ssizetcolumn,i;intvolatile
task;longretval;/**Wemightsleepgettingthepage,sogetitfirst.*/retval=-ENOMEM;buffer=(char*)getfreepage(GFPKERNEL);if(!buffer)gotoout;retval=-EINVAL;r
eadlock(&tasklistlock);p=findtaskbypid(pid);readunlock(&tasklistlock);/*FIXME!!Thisshouldbedoneafterthelastuse*/if(!p)gotofreepageout;if(!p->mm||p->
mm==&initmm||count==0)gotogetlenout;/*Checkwhetherthemmapscouldchangeifwesleep*/volatiletask=(p!=current||atomicread(&p->mm->count)>1);/*decodefpos*
/lineno=*ppos>>MAPSLINESHIFT;column=*ppos&(MAPSLINELENGTH-1);/*quicklygotolinelineno*/for(map=p->mm->mmap,i=0;map&&(i<lineno);map=map->vmnext,i++)co

Hosted by uCoz