linux中命令who的实现
实现了linux中w ho 命令,采用了缓冲机制,一次从utmp文件中读取16条数据,这样可以大大提高性能。
下面是代码,采用了缓冲机制:
可以对比一下性能,记录少的情况下不明显,但是在记录超过1000条时就可以明显看出来了。这个大家可以做一下实验。
这个who命令实现的还算比较完美。
下面是代码,采用了缓冲机制:
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
下面的代码没有采用缓冲机制,每次读取一条记录:
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
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命令实现的还算比较完美。