"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "gmemusage-0.2/proc.c" of archive gmemusage-0.2.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * proc.c:
3 * interface to process table entry in /proc
4 *
5 * Copyright (C) 1997, 1998 by Raju Mathur (raju@sgi.com)
6 *
7 * See file COPYING (included in this distribution) for copyright information.
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <dirent.h>
13 #include <sys/stat.h>
14 #include "common.h"
15 /*
16 * memory (in Kbytes)
17 */
18 int
19 sysmem = 0 ,
20 kernelmem = 0 ,
21 freemem = 0 ,
22 buffermem = 0 ;
23 /*
24 * Set values for various memory usages
25 */
26 static void
27 SetMemInfo ( void )
28 {
29 struct stat
30 s ;
31 char
32 buf [128] ;
33 FILE
34 *meminfo ;
35 int
36 totalmem ;
37 const char
38 *MemLine = "Mem:" ;
39 const int
40 MemLineLen = strlen ( MemLine ) ;
41 /*
42 * Cheap way to get amount of installed mem in the computer -- get size of
43 * /proc/kcore.
44 */
45 if ( stat ( "/proc/kcore" , &s ) < 0 )
46 {
47 fprintf ( stderr , "%s: cannot stat /proc/kcore" , progname ) ;
48 perror ( "" ) ;
49 exit ( 1 ) ;
50 }
51 sysmem = s . st_size ; /* in Kilobytes */
52 /*
53 * Read /proc/meminfo to get usable memory and buffers. Presumably buffers
54 * should be considered a part of the kernel memory.
55 */
56 if ( ( meminfo = fopen ( "/proc/meminfo" , "r" ) ) == NULL )
57 {
58 fprintf ( stderr , "%s: cannot open /proc/meminfo" , progname ) ;
59 perror ( "" ) ;
60 exit ( 1 ) ;
61 }
62 while ( fgets ( buf , sizeof ( buf ) , meminfo ) )
63 {
64 if ( !strncmp ( buf , MemLine , MemLineLen ) )
65 {
66 /* Mem: total used free shared buffers cached */
67 sscanf ( buf , "%*s %d %*d %d %*d %d" , &totalmem , &freemem ,
68 &buffermem ) ;
69 break ;
70 }
71 }
72 sysmem /= 1024 ;
73 totalmem /= 1024 ;
74 freemem /= 1024 ;
75 buffermem /= 1024 ;
76 kernelmem = sysmem - totalmem ;
77 fclose ( meminfo ) ;
78 return ;
79 }
80 /*
81 * Read /proc to get info about processes.
82 * As a side effect :-) also set variables related to main memory.
83 */
84 void
85 makeProcs ( void )
86 {
87 DIR
88 *proc ;
89 struct dirent
90 *procdir ;
91 FILE
92 *StatusFile ;
93 char
94 buf [128] ;
95 char
96 procName [14] ;
97 int
98 procSize ,
99 procRSS ,
100 procData ,
101 procStk ,
102 procExe ;
103 const char
104 *NameLine = "Name:" ,
105 *VmSizeLine = "VmSize:" ,
106 *VmRSSLine = "VmRSS" ,
107 *VmDataLine = "VmData" ,
108 *VmStkLine = "VmStk" ,
109 *VmExeLine = "VmExe" ;
110 const int
111 NameLineLen = strlen ( NameLine ) ,
112 VmSizeLineLen = strlen ( VmSizeLine ) ,
113 VmDataLineLen = strlen ( VmDataLine ) ,
114 VmStkLineLen = strlen ( VmStkLine ) ,
115 VmExeLineLen = strlen ( VmExeLine ) ,
116 VmRSSLineLen = strlen ( VmRSSLine ) ;
117
118 if ( ( proc = opendir ( "/proc" ) ) == NULL )
119 {
120 fprintf ( stderr , "%s: unable to open /proc" , progname ) ;
121 perror ( "" ) ;
122 exit ( 1 ) ;
123 }
124 ClearProcs () ;
125 /*
126 * Get memory info
127 */
128 SetMemInfo () ;
129 /*
130 * Make sure that the first process is the kernel. We'll be slightly off,
131 * but the alternatives (adding this after the rest of the process list
132 * has been made) are too terrible to contemplate.
133 */
134 addProc ( kernelname , kernelmem + buffermem , kernelmem + buffermem ) ;
135 /*
136 * NASTY HACK!
137 * Some screwy feature (or my screwy understanding of /proc) causes the
138 * sum(RSS) for all the procs + kernel + buffers + freemem to become > system
139 * memory. Hence we recalculate system memory based on the actual figures
140 * we get from sum(RSS)+kernel+buffers+freemem
141 */
142 sysmem = 0 ;
143 while ( procdir = readdir ( proc ) )
144 {
145 if ( !index ( "1234567890" , procdir -> d_name [0] ) )
146 {
147 continue ;
148 }
149 sprintf ( buf , "/proc/%s/status" , procdir -> d_name ) ;
150 if ( ( StatusFile = fopen ( buf , "r" ) ) == NULL )
151 {
152 fprintf ( stderr , "%s: cannot open %s for reading" ,
153 progname , buf ) ;
154 perror ( "" ) ;
155 continue ;
156 }
157 procRSS = procSize = procData = procStk = procExe = 0 ;
158 while ( fgets ( buf , sizeof ( buf ) , StatusFile ) )
159 {
160 /*
161 * I hate sscanf's, but am too lazy to replace them with a more elegant,
162 * more efficient method right now. Don't you just love TODO lists?
163 */
164 if ( !strncmp ( buf , NameLine , NameLineLen ) )
165 {
166 /* Name: procName */
167 sscanf ( buf , "%*s %s" , procName ) ;
168 }
169 else if ( !strncmp ( buf , VmSizeLine , VmSizeLineLen ) )
170 {
171 /* VmSize: procSize kB */
172 sscanf ( buf , "%*s %d" , &procSize ) ;
173 }
174 else if ( !strncmp ( buf , VmRSSLine , VmRSSLineLen ) )
175 {
176 /* VmRSS: procRSS kB */
177 sscanf ( buf , "%*s %d" , &procRSS ) ;
178 }
179 else if ( !strncmp ( buf , VmDataLine , VmDataLineLen ) )
180 {
181 /* VmData: procData kB */
182 sscanf ( buf , "%*s %d" , &procData ) ;
183 }
184 else if ( !strncmp ( buf , VmStkLine , VmStkLineLen ) )
185 {
186 /* VmStk: procStk kB */
187 sscanf ( buf , "%*s %d" , &procStk ) ;
188 }
189 else if ( !strncmp ( buf , VmExeLine , VmExeLineLen ) )
190 {
191 /* VmExe: procExe kB */
192 sscanf ( buf , "%*s %d" , &procExe ) ;
193 }
194 }
195 fclose ( StatusFile ) ;
196 addProc ( procName , procSize , procData + procStk + procExe ) ;
197 sysmem += procData + procStk + procExe ;
198 }
199 closedir ( proc ) ;
200 sysmem += kernelmem + buffermem + freemem ;
201 addProc ( freename , freemem , freemem ) ;
202 return ;
203 } /* makeProcs */
204
205 #ifdef DEBUG
206 void
207 printProcs ( void )
208 {
209 struct ProcInfo
210 *pi ,
211 *procs ;
212 int
213 nprocs ,
214 nprocs2 ,
215 totmem ;
216 register int
217 i ;
218 printf ( "%-20s%8s%8s%8s\n" , "Name" , "Memory" , "RSS" , "Number" ) ;
219 totmem = nprocs2 = 0 ;
220 procs = AllProcs ( &nprocs ) ;
221 for ( i = 0 ; i < nprocs ; i++ )
222 {
223 pi = &procs[i] ;
224 printf ( "%-20s%8d%8d%8d\n" , pi -> procname , pi -> totMem ,
225 pi -> totRSS , pi -> nProcs ) ;
226 nprocs2 += pi -> nProcs ;
227 if ( strcmp ( pi -> procname , kernelname ) )
228 {
229 totmem += pi -> totRSS ;
230 }
231 }
232 printf ( "%d procs\n" , nprocs ) ;
233 printf ( "Mem: %d procs, %d total, %d kernel, %d buffers, %d free\n" ,
234 totmem , sysmem , kernelmem , buffermem , freemem ) ;
235 }
236 char *progname ;
237 void
238 main ( int argc , char **argv )
239 {
240 register int i = 0 ;
241 progname = *argv ;
242
243 while ( 1 )
244 {
245 makeProcs () ;
246 printProcs () ;
247 printf ( "\n" ) ;
248 sleep ( 5 ) ;
249 }
250 }
251 #endif /* DEBUG */