]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/readprofile.c
Imported from util-linux-2.9v tarball.
[thirdparty/util-linux.git] / sys-utils / readprofile.c
1 /*
2 * readprofile.c - used to read /proc/profile
3 *
4 * Copyright (C) 1994,1996 Alessandro Rubini (rubini@ipvvis.unipv.it)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
23 * - added Native Language Support
24 */
25
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include "nls.h"
35
36 #define RELEASE "2.0, May 1996"
37
38 #define S_LEN 128
39
40 static char *prgname;
41
42 /* These are the defaults */
43 static char defaultmap[]="/usr/src/linux/System.map";
44 static char defaultpro[]="/proc/profile";
45 static char optstring[]="m:p:itvarV";
46
47 void usage()
48 {
49 fprintf(stderr,
50 _("%s: Usage: \"%s [options]\n"
51 "\t -m <mapfile> (default = \"%s\")\n"
52 "\t -p <pro-file> (default = \"%s\")\n"
53 "\t -i print only info about the sampling step\n"
54 "\t -v print verbose data\n"
55 "\t -a print all symbols, even if count is 0\n"
56 "\t -r reset all the counters (root only)\n"
57 "\t -V print version and exit\n")
58 ,prgname,prgname,defaultmap,defaultpro);
59 exit(1);
60 }
61
62 FILE *myopen(char *name, char *mode, int *flag)
63 {
64 static char cmdline[S_LEN];
65
66 if (!strcmp(name+strlen(name)-3,".gz"))
67 {
68 *flag=1;
69 sprintf(cmdline,"zcat %s", name);
70 return popen(cmdline,mode);
71 }
72 *flag=0;
73 return fopen(name,mode);
74 }
75
76 int main (int argc, char **argv)
77 {
78 FILE *pro;
79 FILE *map;
80 int proFd;
81 char *mapFile, *proFile;
82 unsigned int len=0, add0=0, step, index=0;
83 unsigned int *buf, total, fn_len;
84 unsigned int fn_add, next_add; /* current and next address */
85 char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */
86 char mode[8];
87 int c;
88 int optAll=0, optInfo=0, optReset=0, optVerbose=0;
89 char mapline[S_LEN];
90 int maplineno=1;
91 int popenMap; /* flag to tell if popen() has been used */
92
93 #define next (current^1)
94
95 setlocale(LC_ALL, "");
96 bindtextdomain(PACKAGE, LOCALEDIR);
97 textdomain(PACKAGE);
98
99 prgname=argv[0];
100 proFile=defaultpro;
101 mapFile=defaultmap;
102
103 while ((c=getopt(argc,argv,optstring))!=-1)
104 {
105 switch(c)
106 {
107 case 'm': mapFile=optarg; break;
108 case 'p': proFile=optarg; break;
109 case 'a': optAll++; break;
110 case 'i': optInfo++; break;
111 case 'r': optReset++; break;
112 case 'v': optVerbose++; break;
113 case 'V': printf(_("%s Version %s\n"),prgname,RELEASE); exit(0);
114 default: usage();
115 }
116 }
117
118 if (optReset)
119 {
120 /* try to become root, just in case */
121 setuid(0);
122 pro=fopen(defaultpro,"w");
123 if (!pro)
124 {perror(proFile); exit(1);}
125 fprintf(pro,_("anything\n"));
126 fclose(pro);
127 exit(0);
128 }
129
130 /*
131 * Use an fd for the profiling buffer, to skip stdio overhead
132 */
133 if ( ((proFd=open(proFile,O_RDONLY)) < 0)
134 || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
135 || (lseek(proFd,0,SEEK_SET)<0) )
136 {
137 fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
138 exit(1);
139 }
140
141 if ( !(buf=malloc(len)) )
142 { fprintf(stderr,"%s: malloc(): %s\n",prgname, strerror(errno)); exit(1); }
143
144 if (read(proFd,buf,len) != len)
145 {
146 fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
147 exit(1);
148 }
149 close(proFd);
150
151 step=buf[0];
152 if (optInfo)
153 {
154 printf(_("Sampling_step: %i\n"),step);
155 exit(0);
156 }
157
158 total=0;
159
160 if (!(map=myopen(mapFile,"r",&popenMap)))
161 {fprintf(stderr,"%s: ",prgname);perror(mapFile);exit(1);}
162
163 while(fgets(mapline,S_LEN,map))
164 {
165 if (sscanf(mapline,"%x %s %s",&fn_add,mode,fn_name)!=3)
166 {
167 fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
168 prgname,mapFile, maplineno);
169 exit(1);
170 }
171 if (strcmp(fn_name,"_stext")) /* only elf works like this */
172 {
173 add0=fn_add;
174 break;
175 }
176 }
177
178 if (!add0)
179 {
180 fprintf(stderr,_("%s: can't find \"_stext\" in %s\n"),prgname, mapFile);
181 exit(1);
182 }
183
184 /*
185 * Main loop.
186 */
187 while(fgets(mapline,S_LEN,map))
188 {
189 unsigned int this=0;
190
191 if (sscanf(mapline,"%x %s %s",&next_add,mode,next_name)!=3)
192 {
193 fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
194 prgname,mapFile, maplineno);
195 exit(1);
196 }
197 if (*mode!='T' && *mode!='t') break; /* only text is profiled */
198
199 while (index < (next_add-add0)/step)
200 this += buf[index++];
201 total += this;
202
203 fn_len = next_add-fn_add;
204 if (fn_len && (this || optAll))
205 {
206 if (optVerbose)
207 printf("%08x %-40s %6i %8.4f\n",
208 fn_add,fn_name,this,this/(double)fn_len);
209 else
210 printf("%6i %-40s %8.4f\n",
211 this,fn_name,this/(double)fn_len);
212 }
213 fn_add=next_add; strcpy(fn_name,next_name);
214 }
215 /* trailer */
216 if (optVerbose)
217 printf("%08x %-40s %6i %8.4f\n",
218 0,"total",total,total/(double)(fn_add-add0));
219 else
220 printf("%6i %-40s %8.4f\n",
221 total,_("total"),total/(double)(fn_add-add0));
222
223 popenMap ? pclose(map) : fclose(map);
224 exit(0);
225 }
226
227
228