home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / sys-utils / readprofile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  5.3 KB  |  224 lines

  1. /*
  2.  *  readprofile.c - used to read /proc/profile
  3.  *
  4.  *  Copyright (C) 1994 Alessandro Rubini
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>  /* getopt() */
  24. #include <string.h>
  25.  
  26. #define RELEASE "1.1, Jan 1995"
  27.  
  28. #define S_LEN 128
  29.  
  30. static char *prgname;
  31.  
  32. /* These are the defaults and they cna be changed */
  33. static char defaultmap1[]="/usr/src/linux/System.map";
  34. static char defaultmap2[]="/usr/src/linux/zSystem.map";
  35. static char defaultpro[]="/proc/profile";
  36. static char optstring[]="m:p:itvarV";
  37.  
  38. void usage()
  39. {
  40.   fprintf(stderr,
  41.           "%s: Usage: \"%s [options]\n"
  42.           "\t -m <mapfile>  (default = \"%s\")\n"
  43.           "\t -p <pro-file> (default = \"%s\")\n"
  44.           "\t -i            print only info about the sampling step\n"
  45.           "\t -t            print terse data\n"
  46.           "\t -v            print verbose data\n"
  47.           "\t -a            print all symbols, even if count is 0\n"
  48.           "\t -r            reset all the counters (root only)\n"
  49.           "\t -V            print version and exit\n"
  50.           ,prgname,prgname,defaultmap1,defaultpro);
  51.   exit(1);
  52. }
  53.  
  54. FILE *myopen(char *name, char *mode, int *flag)
  55. {
  56. static char cmdline[S_LEN];
  57.  
  58.   if (!strcmp(name+strlen(name)-3,".gz"))
  59.     {
  60.     *flag=1;
  61.     sprintf(cmdline,"zcat %s", name);
  62.     return popen(cmdline,mode);
  63.     }
  64.   *flag=0;
  65.   return fopen(name,mode);
  66. }
  67.  
  68. int main (int argc, char **argv)
  69. {
  70. FILE *pro;
  71. FILE *map;
  72. unsigned long l;
  73. char *proFile;
  74. char *mapFile;
  75. int add, step;
  76. int fn_add[2];            /* current and next address */
  77. char fn_name[2][S_LEN];   /* current and next name */
  78. char mode[8];
  79. int i,c,current=0;
  80. int optAll=0, optInfo=0, optReset=0, optTerse=0, optVerbose=0;
  81. char mapline[S_LEN];
  82. int maplineno=1;
  83. int popenMap, popenPro;   /* flags to tell if popen() is used */
  84.  
  85. #define next (current^1)
  86.  
  87.   prgname=argv[0];
  88.   proFile=defaultpro;
  89.   mapFile=defaultmap1;
  90.  
  91.   while ((c=getopt(argc,argv,optstring))!=-1)
  92.     {
  93.     switch(c)
  94.       {
  95.       case 'm': mapFile=optarg; break;
  96.       case 'p': proFile=optarg; break;
  97.       case 'a': optAll++;       break;
  98.       case 'i': optInfo++;      break;
  99.       case 't': optTerse++;     break;
  100.       case 'r': optReset++;     break;
  101.       case 'v': optVerbose++;   break;
  102.       case 'V': printf("%s Version %s\n",prgname,RELEASE); exit(0);
  103.       default: usage();
  104.       }
  105.     }
  106.  
  107.   if (optReset)
  108.     {
  109.     pro=fopen(defaultpro,"w");
  110.     if (!pro)
  111.       {perror(proFile); exit(1);}
  112.     fprintf(pro,"anything\n");
  113.     fclose(pro);
  114.     exit(0);
  115.     }
  116.  
  117.   if (!(pro=myopen(proFile,"r",&popenPro))) 
  118.     {fprintf(stderr,"%s: ",prgname);perror(proFile);exit(1);}
  119.  
  120.   /*
  121.    * In opening the map file, try both the default names, but exit
  122.    * at first fail if the filename was specified on cmdline
  123.    */
  124.   for (map=NULL; map==NULL; )
  125.     {
  126.     if (!(map=myopen(mapFile,"r",&popenMap)))
  127.       {
  128.       fprintf(stderr,"%s: ",prgname);perror(mapFile);
  129.       if (mapFile!=defaultmap1) exit(1);
  130.       mapFile=defaultmap2;
  131.       }
  132.     }
  133.  
  134. #define NEXT_WORD(where) \
  135.         (fread((void *)where, 1,sizeof(unsigned long),pro), feof(pro) ? 0 : 1)
  136.  
  137.   /*
  138.    * Init the 'next' field
  139.    */
  140.   if (!fgets(mapline,S_LEN,map))
  141.     {
  142.     fprintf(stderr,"%s: %s(%i): premature EOF\n",prgname,mapFile,maplineno);
  143.     exit(1);
  144.     }
  145.   if (sscanf(mapline,"%x %s %s",&(fn_add[next]),mode,fn_name[next])!=3)
  146.     {
  147.     fprintf(stderr,"%s: %s(%i): wrong map line\n",prgname,mapFile, maplineno);
  148.     exit(1);
  149.     }
  150.  
  151.   add=0;
  152.  
  153.   if (!NEXT_WORD(&step))
  154.     {
  155.     fprintf(stderr,"%s: %s: premature EOF\n",prgname,proFile);
  156.     exit(1);
  157.     }
  158.  
  159.   if (optInfo)
  160.     {
  161.     printf(optTerse ? "%i\n" : "The sampling step in the kernel is %i bytes\n",
  162.            step);
  163.     exit(0);
  164.     } 
  165.  
  166.   /*
  167.    * The main loop is build around the mapfile
  168.    */
  169.   
  170.   while(current^=1, maplineno++, fgets(mapline,S_LEN,map))
  171.     {
  172.     int fn_len;
  173.     int count=0;
  174.  
  175.  
  176.     if (sscanf(mapline,"%x %s %s",&(fn_add[next]),mode,fn_name[next])!=3)
  177.       {
  178.       fprintf(stderr,"%s: %s(%i): wrong map line\n",
  179.               prgname,mapFile, maplineno);
  180.       exit(1);
  181.       }
  182.  
  183.     if (!(fn_len=fn_add[next]-fn_add[current]))
  184.       continue;
  185.  
  186.     if (*mode=='d' || *mode=='D') break; /* only text is profiled */
  187.  
  188.     while (add<fn_add[next])
  189.       {
  190.       if (!NEXT_WORD(&l))
  191.         {
  192.         fprintf(stderr,"%s: %s: premature EOF\n",prgname,proFile);
  193.         exit(1);
  194.         }
  195.       count+=l; add+=step;
  196.       }
  197.  
  198.     if (count || optAll)
  199.       {
  200.       if (optTerse)
  201.         printf("%i %s %lg\n",
  202.                count,fn_name[current],count/(double)fn_len);
  203.       else if (optVerbose)
  204.         printf("%08x %-40s %6i %8.4lf\n",
  205.                fn_add[current],fn_name[current],count,count/(double)fn_len);
  206.       else
  207.         printf("%6i %-40s %8.4lf\n",
  208.                count,fn_name[current],count/(double)fn_len);
  209.       }
  210.     }
  211.  
  212.   if (feof(map))
  213.     {
  214.     fprintf(stderr,"%s: %s(%i): premature EOF\n",prgname,mapFile,maplineno);
  215.     exit(1);
  216.     }
  217.     
  218.   popenPro ? pclose(pro) : fclose(pro);
  219.   popenMap ? pclose(map) : fclose(map);
  220.   exit(0);
  221. }
  222.  
  223.  
  224.