/**linux/fs/proc/array.c**Copyright(C)1992byLinusTorvalds*basedonideasbyDarrenSenn**Fixes:*Michael.K.Johnson:stat,statmextensions.*<johnsonm@stolaf
.edu>**PaulineMiddelink:Madecmdline,envlineonlybreakat'\0's,to*makesureSET_PROCTITLEworks.Alsoremoved*bad'!'whichforcedaddressrecalculationfor*EVER
Ycharacteronthecurrentpage.*<middelin@polyware.iaf.nl>**DannyterHaar:addedcpuinfo*<dth@cistron.nl>**AlessandroRubini:profileextension.*<rubini@ipvv
is.unipv.it>**JeffTranter:addedBogoMipsfieldtocpuinfo*<Jeff_Tranter@Mitel.COM>**BrunoHaible:remove4Klimitforthemapsfile*<haible@ma2s2.mathematik.un
i-karlsruhe.de>**YvesArrouye:removeremovaloftrailingspacesinget_array.*<Yves.Arrouye@marin.fdn.fr>**JeromeForissier:addedper-CPUtimeinformationto/p
roc/stat*and/proc/<pid>/cpuextension*<forissier@isia.cma.fr>*-Incorporationandnon-SMPsafeoperation*offorissierpatchin2.1.78by*HansMarcus<crowbar@co
ncepts.nl>**aeb@cwi.nl:/proc/partitions***AlanCox:securityfixes.*<Alan.Cox@linux.org>**GerhardWichert:addedBIGMEMsupport*SiemensAG<Gerhard.Wichert@
pdb.siemens.de>*/#include<linux/types.h>#include<linux/errno.h>#include<linux/sched.h>#include<linux/kernel.h>#include<linux/kernel_stat.h>#include
<linux/tty.h>#include<linux/user.h>#include<linux/a.out.h>#include<linux/string.h>#include<linux/mman.h>#include<linux/proc_fs.h>#include<linux/iop
ort.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>#includ
e<linux/signal.h>#include<asm/uaccess.h>#include<asm/pgtable.h>#include<asm/io.h>#defineLOAD_INT(x)((x)>>FSHIFT)#defineLOAD_FRAC(x)LOAD_INT(((x)&(F
IXED_1-1))*100)#ifdefCONFIG_DEBUG_MALLOCintget_malloc(char*buffer);#endifstaticintopen_kcore(structinode*inode,structfile*filp){returncapable(CAP_S
YS_RAWIO)?0:-EPERM;}staticssize_tread_core(structfile*file,char*buf,size_tcount,loff_t*ppos){unsignedlongp=*ppos,memsize;ssize_tread;ssize_tcount1;
char*pnt;structuserdump;#ifdefined(__i386__)||defined(__mc68000__)#defineFIRST_MAPPEDPAGE_SIZE/*wedon'thavepage0mappedonx86..*/#else#defineFIRST_MA
PPED0#endifmemset(&dump,0,sizeof(structuser));dump.magic=CMAGIC;dump.u_dsize=max_mapnr;#ifdefined(__i386__)dump.start_code=PAGE_OFFSET;#endif#ifdef
__alpha__dump.start_data=PAGE_OFFSET;#endifmemsize=(max_mapnr+1)<<PAGE_SHIFT;if(p>=memsize)return0;if(count>memsize-p)count=memsize-p;read=0;if(p<s
izeof(structuser)&&count>0){count1=count;if(p+count1>sizeof(structuser))count1=sizeof(structuser)-p;pnt=(char*)&dump+p;copy_to_user(buf,(void*)pnt,
count1);buf+=count1;p+=count1;count-=count1;read+=count1;}if(count>0&&p<PAGE_SIZE+FIRST_MAPPED){count1=PAGE_SIZE+FIRST_MAPPED-p;if(count1>count)cou
nt1=count;clear_user(buf,count1);buf+=count1;p+=count1;count-=count1;read+=count1;}if(count>0){copy_to_user(buf,(void*)(PAGE_OFFSET+p-PAGE_SIZE),co
unt);read+=count;}*ppos+=read;returnread;}staticstructfile_operationsproc_kcore_operations={NULL,/*lseek*/read_core,NULL,/*write*/NULL,/*readdir*/N
ULL,/*poll*/NULL,/*ioctl*/NULL,/*mmap*/open_kcore};structinode_operationsproc_kcore_inode_operations={&proc_kcore_operations,};/**Thisfunctionacces
sesprofilinginformation.Thereturneddatais*binary:thesamplingstepandtheactualcontentsoftheprofile*buffer.Useoftheprogramreadprofileisrecommendedinor
derto*getmeaningfulinfooutofthesedata.*/staticssize_tread_profile(structfile*file,char*buf,size_tcount,loff_t*ppos){unsignedlongp=*ppos;ssize_tread
;char*pnt;unsignedintsample_step=1<<prof_shift;if(p>=(prof_len+1)*sizeof(unsignedint))return0;if(count>(prof_len+1)*sizeof(unsignedint)-p)count=(pr
of_len+1)*sizeof(unsignedint)-p;read=0;while(p<sizeof(unsignedint)&&count>0){put_user(*((char*)(&sample_step)+p),buf);buf++;p++;count--;read++;}pnt
=(char*)prof_buffer+p-sizeof(unsignedint);copy_to_user(buf,(void*)pnt,count);read+=count;*ppos+=read;returnread;}/**Writingto/proc/profileresetsthe
counters**Writinga'profilingmultiplier'valueintoitalsore-setstheprofiling*interruptfrequency,onarchitecturesthatsupportthis.*/staticssize_twrite_pr
ofile(structfile*file,constchar*buf,size_tcount,loff_t*ppos){#ifdef__SMP__externintsetup_profiling_timer(unsignedintmultiplier);if(count==sizeof(in
t)){unsignedintmultiplier;if(copy_from_user(&multiplier,buf,sizeof(int)))return-EFAULT;if(setup_profiling_timer(multiplier))return-EINVAL;}#endifme
mset(prof_buffer,0,prof_len*sizeof(*prof_buffer));returncount;}staticstructfile_operationsproc_profile_operations={NULL,/*lseek*/read_profile,write
_profile,};structinode_operationsproc_profile_inode_operations={&proc_profile_operations,};staticintget_loadavg(char*buffer){inta,b,c;a=avenrun[0]+
(FIXED_1/200);b=avenrun[1]+(FIXED_1/200);c=avenrun[2]+(FIXED_1/200);returnsprintf(buffer,"%d.%02d%d.%02d%d.%02d%d/%d%d\n",LOAD_INT(a),LOAD_FRAC(a),
LOAD_INT(b),LOAD_FRAC(b),LOAD_INT(c),LOAD_FRAC(c),nr_running,nr_tasks,last_pid);}staticintget_kstat(char*buffer){inti,len;unsignedsum=0;externunsig
nedlongtotal_forks;unsignedlongticks;ticks=jiffies*smp_num_cpus;#ifndefCONFIG_ARCH_S390for(i=0;i<NR_IRQS;i++)sum+=kstat_irqs(i);#endif#ifdef__SMP__
len=sprintf(buffer,"cpu%u%u%u%lu\n",kstat.cpu_user,kstat.cpu_nice,kstat.cpu_system,jiffies*smp_num_cpus-(kstat.cpu_user+kstat.cpu_nice+kstat.cpu_sy
stem));for(i=0;i<smp_num_cpus;i++)len+=sprintf(buffer+len,"cpu%d%u%u%u%lu\n",i,kstat.per_cpu_user[cpu_logical_map(i)],kstat.per_cpu_nice[cpu_logica
l_map(i)],kstat.per_cpu_system[cpu_logical_map(i)],jiffies-(kstat.per_cpu_user[cpu_logical_map(i)]\+kstat.per_cpu_nice[cpu_logical_map(i)]\+kstat.p
er_cpu_system[cpu_logical_map(i)]));len+=sprintf(buffer+len,"disk%u%u%u%u\n""disk_rio%u%u%u%u\n""disk_wio%u%u%u%u\n""disk_rblk%u%u%u%u\n""disk_wblk
%u%u%u%u\n""page%u%u\n"#ifdefCONFIG_ARCH_S390"swap%u%u\n""intr10",#else"swap%u%u\n""intr%u",#endif#elselen=sprintf(buffer,"cpu%u%u%u%lu\n""disk%u%u
%u%u\n""disk_rio%u%u%u%u\n""disk_wio%u%u%u%u\n""disk_rblk%u%u%u%u\n""disk_wblk%u%u%u%u\n""page%u%u\n"#ifdefCONFIG_ARCH_S390"swap%u%u\n""intr10",#el
se"swap%u%u\n""intr%u",#endifkstat.cpu_user,kstat.cpu_nice,kstat.cpu_system,ticks-(kstat.cpu_user+kstat.cpu_nice+kstat.cpu_system),#endifkstat.dk_d
rive[0],kstat.dk_drive[1],kstat.dk_drive[2],kstat.dk_drive[3],kstat.dk_drive_rio[0],kstat.dk_drive_rio[1],kstat.dk_drive_rio[2],kstat.dk_drive_rio[
3],kstat.dk_drive_wio[0],kstat.dk_drive_wio[1],kstat.dk_drive_wio[2],kstat.dk_drive_wio[3],kstat.dk_drive_rblk[0],kstat.dk_drive_rblk[1],kstat.dk_d
rive_rblk[2],kstat.dk_drive_rblk[3],kstat.dk_drive_wblk[0],kstat.dk_drive_wblk[1],kstat.dk_drive_wblk[2],kstat.dk_drive_wblk[3],kstat.pgpgin,kstat.
pgpgout,kstat.pswpin,#ifdefCONFIG_ARCH_S390kstat.pswpout);#elsekstat.pswpout,sum);for(i=0;i<NR_IRQS;i++)len+=sprintf(buffer+len,"%u",kstat_irqs(i))
;#endiflen+=sprintf(buffer+len,"\nctxt%u\n""btime%lu\n""processes%lu\n",kstat.context_swtch,xtime.tv_sec-jiffies/HZ,total_forks);returnlen;}statici
ntget_uptime(char*buffer){unsignedlonguptime;unsignedlongidle;uptime=jiffies;idle=task[0]->times.tms_utime+task[0]->times.tms_stime;/*Theformulafor
thefractionpartsreallyis((t*100)/HZ)%100,butthatwouldoverflowabouteveryfivedaysatHZ==100.Thereforetheidentitya=(a/b)*b+a%bisusedsothatitiscalculate
das(((t/HZ)*100)+((t%HZ)*100)/HZ)%100.Thepartinfrontofthe'+'alwaysevaluatesas0(mod100).Alldivisionsintheaboveformulasaretruncating.ForHZbeingapower
of10,thecalculationssimplifytotheversioninthe#elsepart(iftheprintfformatisadaptedtothesamenumberofdigitsaszeroesinHZ.*/#ifHZ!=100returnsprintf(buff
er,"%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",u
ptime/HZ,uptime%HZ,idle/HZ,idle%HZ);#endif}staticintget_meminfo(char*buffer){structsysinfoi;intlen;si_meminfo(&i);si_swapinfo(&i);len=sprintf(buffe
r,"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.share
dram,i.bufferram,page_cache_size*PAGE_SIZE,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:%8luk
B\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.bu
fferram>>10,page_cache_size<<(PAGE_SHIFT-10),i.totalbig>>10,i.freebig>>10,i.totalswap>>10,i.freeswap>>10);}staticintget_version(char*buffer){extern
char*linux_banner;strcpy(buffer,linux_banner);returnstrlen(buffer);}staticintget_cmdline(char*buffer){externcharsaved_command_line[];returnsprintf(
buffer,"%s\n",saved_command_line);}staticunsignedlongget_phys_addr(structtask_struct*p,unsignedlongptr){pgd_t*page_dir;pmd_t*page_middle;pte_tpte;i
f(!p||!p->mm||ptr>=TASK_SIZE)return0;/*CheckforNULLpgd..shouldn'thappen!*/if(!p->mm->pgd){printk("get_phys_addr:pid%dhasNULLpgd!\n",p->pid);return0
;}page_dir=pgd_offset(p->mm,ptr);if(pgd_none(*page_dir))return0;if(pgd_bad(*page_dir)){printk("badpagedirectoryentry%08lx\n",pgd_val(*page_dir));pg
d_clear(page_dir);return0;}page_middle=pmd_offset(page_dir,ptr);if(pmd_none(*page_middle))return0;if(pmd_bad(*page_middle)){printk("badpagemiddleen
try%08lx\n",pmd_val(*page_middle));pmd_clear(page_middle);return0;}pte=*pte_offset(page_middle,ptr);if(!pte_present(pte))return0;returnpte_page(pte
)+(ptr&~PAGE_MASK);}#include<linux/bigmem.h>staticintget_array(structtask_struct*p,unsignedlongstart,unsignedlongend,char*buffer){unsignedlongaddr;
intsize=0,result=0;charc;if(start>=end)returnresult;for(;;){addr=get_phys_addr(p,start);if(!addr)returnresult;addr=kmap(addr,KM_READ);do{c=*(char*)
addr;if(!c)result=size;if(size<PAGE_SIZE)buffer[size++]=c;else{kunmap(addr,KM_READ);returnresult;}addr++;start++;if(!c&&start>=end){kunmap(addr,KM_
READ);returnresult;}}while(addr&~PAGE_MASK);kunmap(addr-1,KM_READ);}returnresult;}staticintget_env(intpid,char*buffer){structtask_struct*p;read_loc
k(&tasklist_lock);p=find_task_by_pid(pid);read_unlock(&tasklist_lock);/*FIXME!!Thisshouldbedoneafterthelastuse*/if(!p||!p->mm)return0;returnget_arr
ay(p,p->mm->env_start,p->mm->env_end,buffer);}staticintget_arg(intpid,char*buffer){structtask_struct*p;read_lock(&tasklist_lock);p=find_task_by_pid
(pid);read_unlock(&tasklist_lock);/*FIXME!!Thisshouldbedoneafterthelastuse*/if(!p||!p->mm)return0;returnget_array(p,p->mm->arg_start,p->mm->arg_end
,buffer);}/**Thesebracketthesleepingfunctions..*/externvoidscheduling_functions_start_here(void);externvoidscheduling_functions_end_here(void);#def
inefirst_sched((unsignedlong)scheduling_functions_start_here)#definelast_sched((unsignedlong)scheduling_functions_end_here)staticunsignedlongget_wc
han(structtask_struct*p){if(!p||p==current||p->state==TASK_RUNNING)return0;#ifdefined(__i386__){unsignedlongebp,esp,eip;unsignedlongstack_page;intc
ount=0;stack_page=(unsignedlong)p;esp=p->tss.esp;if(!stack_page||esp<stack_page||esp>=8188+stack_page)return0;/*include/asm-i386/system.h:switch_to
()pushesebplast.*/ebp=*(unsignedlong*)esp;do{if(ebp<stack_page||ebp>=8188+stack_page)return0;eip=*(unsignedlong*)(ebp+4);if(eip<first_sched||eip>=l
ast_sched)returneip;ebp=*(unsignedlong*)ebp;}while(count++<16);}#elifdefined(__alpha__)/**Thisonedependsontheframesizeofschedule().Doa*"disasssched
ule"ingdbtofindtheframesize.Also,the*codeassumesthatsleep_on()followsimmediatelyafter*interruptible_sleep_on()andthatadd_timer()follows*immediately
afterinterruptible_sleep().Ugly,isn'tit?*Maybeaddingawchanfieldtotask_structwouldbebetter,*afterall...*/{unsignedlongschedule_frame;unsignedlongpc;
pc=thread_saved_pc(&p->tss);if(pc>=first_sched&&pc<last_sched){schedule_frame=((unsignedlong*)p->tss.ksp)[6];return((unsignedlong*)schedule_frame)[
12];}returnpc;}#elifdefined(__mips__)/**ThesamecommentasontheAlphaapplieshere,too...*/{unsignedlongschedule_frame;unsignedlongpc;pc=thread_saved_pc
(&p->tss);if(pc>=(unsignedlong)interruptible_sleep_on&&pc<(unsignedlong)add_timer){schedule_frame=((unsignedlong*)(long)p->tss.reg30)[16];return(un
signedlong)((unsignedlong*)schedule_frame)[11];}returnpc;}#elifdefined(__mc68000__){unsignedlongfp,pc;unsignedlongstack_page;intcount=0;stack_page=
(unsignedlong)p;fp=((structswitch_stack*)p->tss.ksp)->a6;do{if(fp<stack_page+sizeof(structtask_struct)||fp>=8184+stack_page)return0;pc=((unsignedlo
ng*)fp)[1];/*FIXME:Thisdependsontheorderofthesefunctions.*/if(pc<first_sched||pc>=last_sched)returnpc;fp=*(unsignedlong*)fp;}while(count++<16);}#el
ifdefined(__powerpc__){unsignedlongip,sp;unsignedlongstack_page=(unsignedlong)p;intcount=0;sp=p->tss.ksp;do{sp=*(unsignedlong*)sp;if(sp<stack_page|
|sp>=stack_page+8188)return0;if(count>0){ip=*(unsignedlong*)(sp+4);if(ip<first_sched||ip>=last_sched)returnip;}}while(count++<16);}#elifdefined(__a
rm__){unsignedlongfp,lr;unsignedlongstack_page;intcount=0;stack_page=4096+(unsignedlong)p;fp=get_css_fp(&p->tss);do{if(fp<stack_page||fp>4092+stack
_page)return0;lr=pc_pointer(((unsignedlong*)fp)[-1]);if(lr<first_sched||lr>last_sched)returnlr;fp=*(unsignedlong*)(fp-12);}while(count++<16);}#elif
defined(__sparc__){unsignedlongpc,fp,bias=0;unsignedlongtask_base=(unsignedlong)p;structreg_window*rw;intcount=0;#ifdef__sparc_v9__bias=STACK_BIAS;
#endiffp=p->tss.ksp+bias;do{/*Bogusframepointer?*/if(fp<(task_base+sizeof(structtask_struct))||fp>=(task_base+(2*PAGE_SIZE)))break;rw=(structreg_wi
ndow*)fp;pc=rw->ins[7];if(pc<first_sched||pc>=last_sched)returnpc;fp=rw->ins[6]+bias;}while(++count<16);}#elifdefined(__s390__){unsignedlongksp,bac
kchain,ip;unsignedlongstack_page;intcount=0;stack_page=(unsignedlong)p;ksp=p->tss.ksp;if(!stack_page||ksp<stack_page||ksp>=8188+stack_page)return0;
backchain=(*(unsignedlong*)ksp)&0x7fffffff;do{if(backchain<stack_page||backchain>=8188+stack_page)return0;ip=(*(unsignedlong*)(backchain+56))&0x7ff
fffff;if(ip<first_sched||ip>=last_sched)returnip;backchain=(*(unsignedlong*)backchain)&0x7fffffff;}while(count++<16);}#endifreturn0;}#ifdefined(__i
386__)#defineKSTK_EIP(tsk)(((unsignedlong*)(4096+(unsignedlong)(tsk)))[1019])#defineKSTK_ESP(tsk)(((unsignedlong*)(4096+(unsignedlong)(tsk)))[1022]
)#elifdefined(__alpha__)/**Seearch/alpha/kernel/ptrace.cfordetails.*/#definePT_REG(reg)(PAGE_SIZE-sizeof(structpt_regs)\+(long)&((structpt_regs*)0)
->reg)#defineKSTK_EIP(tsk)\(*(unsignedlong*)(PT_REG(pc)+PAGE_SIZE+(unsignedlong)(tsk)))#defineKSTK_ESP(tsk)((tsk)==current?rdusp():(tsk)->tss.usp)#
elifdefined(__arm__)#defineKSTK_EIP(tsk)(((unsignedlong*)(4096+(unsignedlong)(tsk)))[1022])#defineKSTK_ESP(tsk)(((unsignedlong*)(4096+(unsignedlong
)(tsk)))[1020])#elifdefined(__mc68000__)#defineKSTK_EIP(tsk)\({\unsignedlongeip=0;\if((tsk)->tss.esp0>PAGE_SIZE&&\MAP_NR((tsk)->tss.esp0)<max_mapnr
)\eip=((structpt_regs*)(tsk)->tss.esp0)->pc;\eip;})#defineKSTK_ESP(tsk)((tsk)==current?rdusp():(tsk)->tss.usp)#elifdefined(__powerpc__)#defineKSTK_
EIP(tsk)((tsk)->tss.regs->nip)#defineKSTK_ESP(tsk)((tsk)->tss.regs->gpr[1])#elifdefined(__sparc_v9__)#defineKSTK_EIP(tsk)((tsk)->tss.kregs->tpc)#de
fineKSTK_ESP(tsk)((tsk)->tss.kregs->u_regs[UREG_FP])#elifdefined(__sparc__)#defineKSTK_EIP(tsk)((tsk)->tss.kregs->pc)#defineKSTK_ESP(tsk)((tsk)->ts
s.kregs->u_regs[UREG_FP])#elifdefined(__mips__)#definePT_REG(reg)((long)&((structpt_regs*)0)->reg\-sizeof(structpt_regs))#defineKSTK_TOS(tsk)((unsi
gnedlong)(tsk)+KERNEL_STACK_SIZE-32)#defineKSTK_EIP(tsk)(*(unsignedlong*)(KSTK_TOS(tsk)+PT_REG(cp0_epc)))#defineKSTK_ESP(tsk)(*(unsignedlong*)(KSTK
_TOS(tsk)+PT_REG(regs[29])))#elifdefined(__s390__)#defineKSTK_EIP(tsk)((tsk)->tss.regs->psw.addr)#defineKSTK_ESP(tsk)((tsk)->tss.ksp)#endif/*Gccopt
imizesaway"strlen(x)"forconstantx*/#defineADDBUF(buffer,string)\do{memcpy(buffer,string,strlen(string));\buffer+=strlen(string);}while(0)staticinli
nechar*task_name(structtask_struct*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*reasonstosleep.Thus"running"iszero,and*youcantestforcombinationsofotherswith*simplebittests.*/staticcon
stchar*task_state_array[]={"R(running)",/*0*/"S(sleeping)",/*1*/"D(disksleep)",/*2*/"Z(zombie)",/*4*/"T(stopped)",/*8*/"W(paging)"/*16*/};staticinl
ineconstchar*get_task_state(structtask_struct*tsk){unsignedintstate=tsk->state&(TASK_RUNNING|TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE|TASK_ZOMBIE|TA
SK_STOPPED|TASK_SWAPPING);constchar**p=&task_state_array[0];while(state){p++;state>>=1;}return*p;}staticinlinechar*task_state(structtask_struct*p,c
har*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",get_task
_state(p),p->pid,p->p_pptr->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;}staticinlinechar*task_mem(structtask_struct*p,char*buffer){structmm_struct*mm=p->mm;if(
mm&&mm!=&init_mm){structvm_area_struct*vma=mm->mmap;unsignedlongdata=0,stack=0;unsignedlongexec=0,lib=0;for(vma=mm->mmap;vma;vma=vma->vm_next){unsi
gnedlonglen=(vma->vm_end-vma->vm_start)>>10;if(!vma->vm_file){data+=len;if(vma->vm_flags&VM_GROWSDOWN)stack+=len;continue;}if(vma->vm_flags&VM_WRIT
E)continue;if(vma->vm_flags&VM_EXEC){exec+=len;if(vma->vm_flags&VM_EXECUTABLE)continue;lib+=len;}}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->total_vm<<(PAGE_SHIFT-10),mm->locked_vm<
<(PAGE_SHIFT-10),mm->rss<<(PAGE_SHIFT-10),data-stack,stack,exec-lib,lib);}returnbuffer;}staticvoidcollect_sigign_sigcatch(structtask_struct*p,sigse
t_t*ign,sigset_t*catch){structk_sigaction*k;inti;sigemptyset(ign);sigemptyset(catch);if(p->sig){k=p->sig->action;for(i=1;i<=_NSIG;++i,++k){if(k->sa
.sa_handler==SIG_IGN)sigaddset(ign,i);elseif(k->sa.sa_handler!=SIG_DFL)sigaddset(catch,i);}}}staticinlinechar*task_sig(structtask_struct*p,char*buf
fer){sigset_tign,catch;buffer+=sprintf(buffer,"SigPnd:\t");buffer=render_sigset_t(&p->signal,buffer);*buffer++='\n';buffer+=sprintf(buffer,"SigBlk:
\t");buffer=render_sigset_t(&p->blocked,buffer);*buffer++='\n';collect_sigign_sigcatch(p,&ign,&catch);buffer+=sprintf(buffer,"SigIgn:\t");buffer=re
nder_sigset_t(&ign,buffer);*buffer++='\n';buffer+=sprintf(buffer,"SigCgt:\t");/*Linux2.0uses"SigCgt"*/buffer=render_sigset_t(&catch,buffer);*buffer
++='\n';returnbuffer;}externinlinechar*task_cap(structtask_struct*p,char*buffer){returnbuffer+sprintf(buffer,"CapInh:\t%016x\n""CapPrm:\t%016x\n""C
apEff:\t%016x\n",cap_t(p->cap_inheritable),cap_t(p->cap_permitted),cap_t(p->cap_effective));}staticintget_status(intpid,char*buffer){char*orig=buff
er;structtask_struct*tsk;read_lock(&tasklist_lock);tsk=find_task_by_pid(pid);read_unlock(&tasklist_lock);/*FIXME!!Thisshouldbedoneafterthelastuse*/
if(!tsk)return0;buffer=task_name(tsk,buffer);buffer=task_state(tsk,buffer);buffer=task_mem(tsk,buffer);buffer=task_sig(tsk,buffer);buffer=task_cap(
tsk,buffer);#if__s390__buffer=task_show_regs(tsk,buffer);#endifreturnbuffer-orig;}staticintget_stat(intpid,char*buffer){structtask_struct*tsk;unsig
nedlongvsize,eip,esp,wchan;longpriority,nice;inttty_pgrp;sigset_tsigign,sigcatch;charstate;read_lock(&tasklist_lock);tsk=find_task_by_pid(pid);if(!
tsk){read_unlock(&tasklist_lock);return0;}state=*get_task_state(tsk);vsize=eip=esp=0;if(tsk->mm&&tsk->mm!=&init_mm){structvm_area_struct*vma=tsk->m
m->mmap;while(vma){vsize+=vma->vm_end-vma->vm_start;vma=vma->vm_next;}if((current->fsuid==tsk->euid&&tsk->dumpable&&cap_issubset(tsk->cap_permitted
,current->cap_permitted))||capable(CAP_DAC_OVERRIDE)){eip=KSTK_EIP(tsk);esp=KSTK_ESP(tsk);}}read_unlock(&tasklist_lock);/*FIXME!!Thisshouldbedoneaf
terthelastuse*/wchan=get_wchan(tsk);collect_sigign_sigcatch(tsk,&sigign,&sigcatch);if(tsk->tty)tty_pgrp=tsk->tty->pgrp;elsetty_pgrp=-1;/*scaleprior
ityandnicevaluesfromtimeslicesto-20..20*//*tomakeitlooklikea"normal"Unixpriority/nicevalue*/priority=tsk->counter;priority=20-(priority*10+DEF_PRIO
RITY/2)/DEF_PRIORITY;nice=tsk->priority;nice=20-(nice*20+DEF_PRIORITY/2)/DEF_PRIORITY;returnsprintf(buffer,"%d(%s)%c%d%d%d%d%d%lu%lu\%lu%lu%lu%lu%l
u%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->p_pptr->pid,tsk->pgrp,tsk->session,tsk->tty?kd
ev_t_to_nr(tsk->tty->device):0,tty_pgrp,tsk->flags,tsk->min_flt,tsk->cmin_flt,tsk->maj_flt,tsk->cmaj_flt,tsk->times.tms_utime,tsk->times.tms_stime,
tsk->times.tms_cutime,tsk->times.tms_cstime,priority,nice,0UL/*removed*/,tsk->it_real_value,tsk->start_time,vsize,tsk->mm?tsk->mm->rss:0,/*youmight
wanttoshiftthisleft3*/tsk->rlim?tsk->rlim[RLIMIT_RSS].rlim_cur:0,tsk->mm?tsk->mm->start_code:0,tsk->mm?tsk->mm->end_code:0,tsk->mm?tsk->mm->start_s
tack:0,esp,eip,/*Thesignalinformationhereisobsolete.*ItmustbedecimalforLinux2.0compatibility.*Use/proc/#/statusforreal-timesignals.*/tsk->signal.si
g[0]&0x7fffffffUL,tsk->blocked.sig[0]&0x7fffffffUL,sigign.sig[0]&0x7fffffffUL,sigcatch.sig[0]&0x7fffffffUL,wchan,tsk->nswap,tsk->cnswap,tsk->exit_s
ignal,tsk->processor);}staticinlinevoidstatm_pte_range(pmd_t*pmd,unsignedlongaddress,unsignedlongsize,int*pages,int*shared,int*dirty,int*total){pte
_t*pte;unsignedlongend;if(pmd_none(*pmd))return;if(pmd_bad(*pmd)){printk("statm_pte_range:badpmd(%08lx)\n",pmd_val(*pmd));pmd_clear(pmd);return;}pt
e=pte_offset(pmd,address);address&=~PMD_MASK;end=address+size;if(end>PMD_SIZE)end=PMD_SIZE;do{pte_tpage=*pte;address+=PAGE_SIZE;pte++;if(pte_none(p
age))continue;++*total;if(!pte_present(page))continue;++*pages;if(pte_dirty(page))++*dirty;if(MAP_NR(pte_page(page))>=max_mapnr)continue;if(atomic_
read(&mem_map[MAP_NR(pte_page(page))].count)>1)++*shared;}while(address<end);}staticinlinevoidstatm_pmd_range(pgd_t*pgd,unsignedlongaddress,unsigne
dlongsize,int*pages,int*shared,int*dirty,int*total){pmd_t*pmd;unsignedlongend;if(pgd_none(*pgd))return;if(pgd_bad(*pgd)){printk("statm_pmd_range:ba
dpgd(%08lx)\n",pgd_val(*pgd));pgd_clear(pgd);return;}pmd=pmd_offset(pgd,address);address&=~PGDIR_MASK;end=address+size;if(end>PGDIR_SIZE)end=PGDIR_
SIZE;do{statm_pte_range(pmd,address,end-address,pages,shared,dirty,total);address=(address+PMD_SIZE)&PMD_MASK;pmd++;}while(address<end);}staticvoid
statm_pgd_range(pgd_t*pgd,unsignedlongaddress,unsignedlongend,int*pages,int*shared,int*dirty,int*total){while(address<end){statm_pmd_range(pgd,addr
ess,end-address,pages,shared,dirty,total);address=(address+PGDIR_SIZE)&PGDIR_MASK;pgd++;}}staticintget_statm(intpid,char*buffer){structtask_struct*
tsk;intsize=0,resident=0,share=0,trs=0,lrs=0,drs=0,dt=0;read_lock(&tasklist_lock);tsk=find_task_by_pid(pid);read_unlock(&tasklist_lock);/*FIXME!!Th
isshouldbedoneafterthelastuse*/if(!tsk)return0;if(tsk->mm&&tsk->mm!=&init_mm){structvm_area_struct*vma=tsk->mm->mmap;while(vma){pgd_t*pgd=pgd_offse
t(tsk->mm,vma->vm_start);intpages=0,shared=0,dirty=0,total=0;statm_pgd_range(pgd,vma->vm_start,vma->vm_end,&pages,&shared,&dirty,&total);resident+=
pages;share+=shared;dt+=dirty;size+=total;if(vma->vm_flags&VM_EXECUTABLE)trs+=pages;/*text*/elseif(vma->vm_flags&VM_GROWSDOWN)drs+=pages;/*stack*/e
lseif(vma->vm_end>0x60000000)lrs+=pages;/*library*/elsedrs+=pages;vma=vma->vm_next;}}returnsprintf(buffer,"%d%d%d%d%d%d%d\n",size,resident,share,tr
s,lrs,drs,dt);}/**Thewaywesupportsyntheticfiles>4K*-withoutstoringtheircontentsinsomebufferand*-withoutwalkingthroughtheentiresyntheticfileuntilwer
eachthe*positionoftherequesteddata*istocleverlyencodethecurrentpositioninthefile'sf_posfield.*Thereisnorequirementthataread()callwhichreturns`count
'bytes*ofdataincreasesf_posbyexactly`count'.**ThisideaisLinus'one.Brunoimplementedit.*//**Forthe/proc/<pid>/mapsfile,weusefixedlengthrecords,eachco
ntaining*asingleline.*/#defineMAPS_LINE_LENGTH4096#defineMAPS_LINE_SHIFT12/**f_pos=(numberofthevmainthetask->mm->mmaplist)*MAPS_LINE_LENGTH*+(index
intotheline)*//*forsystemswithsizeof(void*)==4:*/#defineMAPS_LINE_FORMAT4"%08lx-%08lx%s%08lx%s%lu"#defineMAPS_LINE_MAX449/*sumof8181418151101*//*fo
rsystemswithsizeof(void*)==8:*/#defineMAPS_LINE_FORMAT8"%016lx-%016lx%s%016lx%s%lu"#defineMAPS_LINE_MAX873/*sumof1611614116151101*/#defineMAPS_LINE
_MAXMAPS_LINE_MAX8staticssize_tread_maps(intpid,structfile*file,char*buf,size_tcount,loff_t*ppos){structtask_struct*p;structvm_area_struct*map,*nex
t;char*destptr=buf,*buffer;loff_tlineno;ssize_tcolumn,i;intvolatile_task;longretval;/**Wemightsleepgettingthepage,sogetitfirst.*/retval=-ENOMEM;buf
fer=(char*)__get_free_page(GFP_KERNEL);if(!buffer)gotoout;retval=-EINVAL;read_lock(&tasklist_lock);p=find_task_by_pid(pid);read_unlock(&tasklist_lo
ck);/*FIXME!!Thisshouldbedoneafterthelastuse*/if(!p)gotofreepage_out;if(!p->mm||p->mm==&init_mm||count==0)gotogetlen_out;/*Checkwhetherthemmapscoul
dchangeifwesleep*/volatile_task=(p!=current||atomic_read(&p->mm->count)>1);/*decodef_pos*/lineno=*ppos>>MAPS_LINE_SHIFT;column=*ppos&(MAPS_LINE_LEN
GTH-1);/*quicklygotolinelineno*/for(map=p->mm->mmap,i=0;map&&(i<lineno);map=map->vm_next,i++)continue;for(;map;map=next){/*producethenextline*/char
*line;charstr[5],*cp=str;intflags;kdev_tdev;unsignedlongino;intmaxlen=(sizeof(void*)==4)?MAPS_LINE_MAX4:MAPS_LINE_MAX8;intlen;/**Getthenextvmanow(b
utitwon'tbeusedifwesleep).*/next=map->vm_next;flags=map->vm_flags;*cp++=flags&VM_READ?'r':'-';*cp++=flags&VM_WRITE?'w':'-';*cp++=flags&VM_EXEC?'x':
'-';*cp++=flags&VM_MAYSHARE?'s':'p';*cp++=0;dev=0;ino=0;if(map->vm_file!=NULL){dev=map->vm_file->f_dentry->d_inode->i_dev;ino=map->vm_file->f_dentr

Hosted by uCoz