linux中命令who的实现

linux中命令who的实现

实现了linux中w ho 命令,采用了缓冲机制,一次从utmp文件中读取16条数据,这样可以大大提高性能。

下面是代码,采用了缓冲机制:
  1  /*
  2   * what is diffient to who1 is that we add a buffer area in who2.c.
  3   *  In this way, the efferency is improved .
  4    */
  5  #include  < stdio.h >
  6  #include  < utmp.h >
  7  #include  < fcntl.h >
  8  #include  < unistd.h >
  9  #include  < stdlib.h >
 10  #include  < time.h >
 11 
 12  #define SHOWHOST           // include remote machine on output
 13 
 14  // -------------------------------------------------------------------------
 15  #define NRECS    16
 16  #define NULLUT ((struct utmp  * )NULL)
 17  #define UTSIZE (sizeof(struct utmp))
 18 
 19  static   char  utmpbuf[NRECS  *  UTSIZE];             // storage
 20  static   int   num_recs;                            // num stored
 21  static   int   cur_rec;                             // next to go
 22  static   int   fd_utmp  =   - 1 ;                        // read from
 23 
 24  int  utmp_open( char   * filename)
 25  {
 26    fd_utmp  =  open(filename, O_RDONLY);
 27    cur_rec  =  num_recs  =   0 ;
 28     return  fd_utmp;
 29  }
 30 
 31  int  utmp_reload()
 32  {
 33     int  amt_read;
 34    amt_read  =  read(fd_utmp, utmpbuf, NRECS  *  UTSIZE);
 35    num_recs  =  amt_read / UTSIZE;                         // how many did we get?
 36    cur_rec  =   0 ;                                        // reset pointer
 37    
 38     return  num_recs;
 39  }
 40 
 41  struct utmp  *  utmp_next()
 42  {
 43    struct utmp  *  recp;
 44     if ( fd_utmp  ==   - 1 return  NULLUT;
 45    
 46     if (cur_rec  ==  num_recs  &&  utmp_reload()  ==   0 return  NULLUT;
 47    
 48    recp  =  (struct utmp  * & utmpbuf[cur_rec  *  UTSIZE];
 49    cur_rec ++ ;
 50     return  recp;
 51  }
 52 
 53  void  utmp_close()
 54  {
 55     if (fd_utmp  !=   - 1 ) close(fd_utmp);   // don't close if not open
 56  }
 57 
 58  // -------------------------------------------------------------------------
 59 
 60  void  show_info(struct utmp  * );
 61  void  showtime( long  timeval);
 62 
 63  int  main()
 64  {
 65    struct utmp  *  utbufp;        // holds pointer to next rec
 66    struct utmp  *  utmp_next();   // return pointer to next
 67    
 68     if (utmp_open(UTMP_FILE)  ==   - 1 )
 69    {
 70      perror(UTMP_FILE);
 71      exit( 1 );
 72    }
 73     while  ( (utbufp  =  utmp_next() )  !=  ((struct utmp  * ) NULL) )
 74      show_info(utbufp);
 75    
 76    utmp_close();
 77     
 78      return   0 ;
 79    
 80  }
 81 
 82  /*
 83   * display contents of the utmp struct 
 84    */
 85  void  show_info( struct utmp  *  utbufp)
 86  {
 87     /*
 88     * remove the blank record
 89     *  the entry ut_type in struct utmp indicate the types
 90     *   USER_PROCESS is the auser process
 91      */
 92     if (utbufp ->  ut_type  !=  USER_PROCESS)  return ;
 93     
 94    printf( " % -8.8s " , utbufp -> ut_name);
 95    printf( "   " );
 96    printf( " % -12.12s " , utbufp -> ut_line);
 97    printf( "   " );
 98     // printf("%101d", utbufp->ut_time);
 99    showtime(utbufp -> ut_time);
100    printf( "   " );
101    #ifdef SHOWHOST
102      printf( " (%s) " , utbufp -> ut_host);
103    #endif
104    printf( " \n " );  
105  }
106 
107  void  showtime( long  timeval)
108  {
109     /*
110     * display time
111      */
112      char   * cp;
113     cp  =  ctime( & timeval);
114     printf( " %12.12s " , cp + 4 );
115  }
116 
下面的代码没有采用缓冲机制,每次读取一条记录:
 1  #include  < stdio.h >
 2  #include  < utmp.h >
 3  #include  < fcntl.h >
 4  #include  < unistd.h >
 5  #include  < stdlib.h >
 6  #include  < time.h >
 7 
 8  #define SHOWHOST           // include remote machine on output
 9 
10  void  show_info(struct utmp  * );
11  void  showtime( long  timeval);
12 
13  int  main()
14  {
15    struct utmp current_record;     // read info into here
16     int               utmpfd;            // read from this descriptor
17     int             reclen  =  sizeof(current_record);   // how many bytes to read
18    
19     if ( (utmpfd  =  open(UTMP_FILE, O_RDONLY))  ==   - 1 )
20    {
21      perror(UTMP_FILE);   // UTMP_FILE is in utmp.h
22      exit( 1 );
23    }
24       /*
25     * read data structure from UTMP_FILE
26      */
27     while ( read(utmpfd,  & current_record, reclen)  ==  reclen)
28          show_info( & current_record);
29    
30    close(utmpfd);
31    
32 
33    //  return 0;
34  }
35 
36  /*
37   * display contents of the utmp struct 
38    */
39  void  show_info( struct utmp  *  utbufp)
40  {
41     /*
42     * remove the blank record
43     *  the entry ut_type in struct utmp indicate the types
44     *   USER_PROCESS is the auser process
45      */
46     if (utbufp ->  ut_type  !=  USER_PROCESS)  return ;
47     
48    printf( " % -8.8s " , utbufp -> ut_name);
49    printf( "   " );
50    printf( " % -12.12s " , utbufp -> ut_line);
51    printf( "   " );
52     // printf("%101d", utbufp->ut_time);
53    showtime(utbufp -> ut_time);
54    printf( "   " );
55    #ifdef SHOWHOST
56      printf( " (%s) " , utbufp -> ut_host);
57    #endif
58    printf( " \n " );  
59  }
60 
61  void  showtime( long  timeval)
62  {
63     /*
64     * display time
65      */
66      char   * cp;
67     cp  =  ctime( & timeval);
68     printf( " %12.12s " , cp + 4 );
69  }
70 

可以对比一下性能,记录少的情况下不明显,但是在记录超过1000条时就可以明显看出来了。这个大家可以做一下实验。

这个who命令实现的还算比较完美。

你可能感兴趣的:(linux中命令who的实现)