summaryrefslogtreecommitdiffstats
path: root/sys-utils/readprofile.c
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:32 +0100
committerKarel Zak2006-12-07 00:25:32 +0100
commit6dbe3af945a63f025561abb83275cee9ff06c57b (patch)
tree19e59eac8ac465b5bc409b5adf815b582c92f633 /sys-utils/readprofile.c
downloadkernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.gz
kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.xz
kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.zip
Imported from util-linux-2.2 tarball.
Diffstat (limited to 'sys-utils/readprofile.c')
-rw-r--r--sys-utils/readprofile.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/sys-utils/readprofile.c b/sys-utils/readprofile.c
new file mode 100644
index 000000000..58234f6af
--- /dev/null
+++ b/sys-utils/readprofile.c
@@ -0,0 +1,223 @@
+/*
+ * readprofile.c - used to read /proc/profile
+ *
+ * Copyright (C) 1994 Alessandro Rubini
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> /* getopt() */
+#include <string.h>
+
+#define RELEASE "1.1, Jan 1995"
+
+#define S_LEN 128
+
+static char *prgname;
+
+/* These are the defaults and they cna be changed */
+static char defaultmap1[]="/usr/src/linux/System.map";
+static char defaultmap2[]="/usr/src/linux/zSystem.map";
+static char defaultpro[]="/proc/profile";
+static char optstring[]="m:p:itvarV";
+
+void usage()
+{
+ fprintf(stderr,
+ "%s: Usage: \"%s [options]\n"
+ "\t -m <mapfile> (default = \"%s\")\n"
+ "\t -p <pro-file> (default = \"%s\")\n"
+ "\t -i print only info about the sampling step\n"
+ "\t -t print terse data\n"
+ "\t -v print verbose data\n"
+ "\t -a print all symbols, even if count is 0\n"
+ "\t -r reset all the counters (root only)\n"
+ "\t -V print version and exit\n"
+ ,prgname,prgname,defaultmap1,defaultpro);
+ exit(1);
+}
+
+FILE *myopen(char *name, char *mode, int *flag)
+{
+static char cmdline[S_LEN];
+
+ if (!strcmp(name+strlen(name)-3,".gz"))
+ {
+ *flag=1;
+ sprintf(cmdline,"zcat %s", name);
+ return popen(cmdline,mode);
+ }
+ *flag=0;
+ return fopen(name,mode);
+}
+
+int main (int argc, char **argv)
+{
+FILE *pro;
+FILE *map;
+unsigned long l;
+char *proFile;
+char *mapFile;
+int add, step;
+int fn_add[2]; /* current and next address */
+char fn_name[2][S_LEN]; /* current and next name */
+char mode[8];
+int i,c,current=0;
+int optAll=0, optInfo=0, optReset=0, optTerse=0, optVerbose=0;
+char mapline[S_LEN];
+int maplineno=1;
+int popenMap, popenPro; /* flags to tell if popen() is used */
+
+#define next (current^1)
+
+ prgname=argv[0];
+ proFile=defaultpro;
+ mapFile=defaultmap1;
+
+ while ((c=getopt(argc,argv,optstring))!=-1)
+ {
+ switch(c)
+ {
+ case 'm': mapFile=optarg; break;
+ case 'p': proFile=optarg; break;
+ case 'a': optAll++; break;
+ case 'i': optInfo++; break;
+ case 't': optTerse++; break;
+ case 'r': optReset++; break;
+ case 'v': optVerbose++; break;
+ case 'V': printf("%s Version %s\n",prgname,RELEASE); exit(0);
+ default: usage();
+ }
+ }
+
+ if (optReset)
+ {
+ pro=fopen(defaultpro,"w");
+ if (!pro)
+ {perror(proFile); exit(1);}
+ fprintf(pro,"anything\n");
+ fclose(pro);
+ exit(0);
+ }
+
+ if (!(pro=myopen(proFile,"r",&popenPro)))
+ {fprintf(stderr,"%s: ",prgname);perror(proFile);exit(1);}
+
+ /*
+ * In opening the map file, try both the default names, but exit
+ * at first fail if the filename was specified on cmdline
+ */
+ for (map=NULL; map==NULL; )
+ {
+ if (!(map=myopen(mapFile,"r",&popenMap)))
+ {
+ fprintf(stderr,"%s: ",prgname);perror(mapFile);
+ if (mapFile!=defaultmap1) exit(1);
+ mapFile=defaultmap2;
+ }
+ }
+
+#define NEXT_WORD(where) \
+ (fread((void *)where, 1,sizeof(unsigned long),pro), feof(pro) ? 0 : 1)
+
+ /*
+ * Init the 'next' field
+ */
+ if (!fgets(mapline,S_LEN,map))
+ {
+ fprintf(stderr,"%s: %s(%i): premature EOF\n",prgname,mapFile,maplineno);
+ exit(1);
+ }
+ if (sscanf(mapline,"%x %s %s",&(fn_add[next]),mode,fn_name[next])!=3)
+ {
+ fprintf(stderr,"%s: %s(%i): wrong map line\n",prgname,mapFile, maplineno);
+ exit(1);
+ }
+
+ add=0;
+
+ if (!NEXT_WORD(&step))
+ {
+ fprintf(stderr,"%s: %s: premature EOF\n",prgname,proFile);
+ exit(1);
+ }
+
+ if (optInfo)
+ {
+ printf(optTerse ? "%i\n" : "The sampling step in the kernel is %i bytes\n",
+ step);
+ exit(0);
+ }
+
+ /*
+ * The main loop is build around the mapfile
+ */
+
+ while(current^=1, maplineno++, fgets(mapline,S_LEN,map))
+ {
+ int fn_len;
+ int count=0;
+
+
+ if (sscanf(mapline,"%x %s %s",&(fn_add[next]),mode,fn_name[next])!=3)
+ {
+ fprintf(stderr,"%s: %s(%i): wrong map line\n",
+ prgname,mapFile, maplineno);
+ exit(1);
+ }
+
+ if (!(fn_len=fn_add[next]-fn_add[current]))
+ continue;
+
+ if (*mode=='d' || *mode=='D') break; /* only text is profiled */
+
+ while (add<fn_add[next])
+ {
+ if (!NEXT_WORD(&l))
+ {
+ fprintf(stderr,"%s: %s: premature EOF\n",prgname,proFile);
+ exit(1);
+ }
+ count+=l; add+=step;
+ }
+
+ if (count || optAll)
+ {
+ if (optTerse)
+ printf("%i %s %lg\n",
+ count,fn_name[current],count/(double)fn_len);
+ else if (optVerbose)
+ printf("%08x %-40s %6i %8.4lf\n",
+ fn_add[current],fn_name[current],count,count/(double)fn_len);
+ else
+ printf("%6i %-40s %8.4lf\n",
+ count,fn_name[current],count/(double)fn_len);
+ }
+ }
+
+ if (feof(map))
+ {
+ fprintf(stderr,"%s: %s(%i): premature EOF\n",prgname,mapFile,maplineno);
+ exit(1);
+ }
+
+ popenPro ? pclose(pro) : fclose(pro);
+ popenMap ? pclose(map) : fclose(map);
+ exit(0);
+}
+
+