#include <stdio.h> #include <stdlib.h> #include <utmp.h> #include <fcntl.h> #include <unistd.h> #include <time.h> void show_info(struct utmp *); void showtime(long); int main() { int fd; struct utmp current_record; int reclen = sizeof(struct utmp); /* UTMP_FILE就是/var/run/utmp.在/usr/include/paths.h下 */ fd = open(UTMP_FILE, O_RDONLY); if (fd == -1) { perror(UTMP_FILE); exit(1); } while (read(fd, ¤t_record, reclen)) show_info(¤t_record); close(fd); return 0; } /* displays the contents of the utmp struct, display nothing if utmp has no user name */ void show_info(struct utmp *utbufp) { if (utbufp->ut_type != USER_PROCESS) return; printf("%-8.8s", utbufp->ut_user); /* The user name */ printf(" "); printf("%-8.8s", utbufp->ut_line); /* The tty name */ printf(" "); showtime(utbufp->ut_time); /* utime */ #ifdef SHOWHOST if (utbufp->ut_host[0] != '\0') printf(" (%s)", utbufp->ut_host); /* the host */ #endif printf("\n"); } /* displays time in a format */ void showtime(long timeval) { char *cp; cp = ctime(&timeval); /* convert time to string */ printf("%20.20s", cp+4); /* %12.12s prints a string 20 chars wide and LIMITS it to 20 chars. cp+4是为了把最前面的星期去掉 */ }
增加了缓冲机制的who命令实现:这样会减少read()函数调用的次数,提高程序效率和性能。
主函数为:who1.c
#include <stdio.h> #include <stdlib.h> #include <utmp.h> #include <fcntl.h> #include <unistd.h> #include <time.h> #include </root/utmplib.c> /* 包含实现缓冲的文件 */ void show_info(struct utmp *); void showtime(long); int main() { int fd; struct utmp *utbufp; int reclen = sizeof(struct utmp); /* UTMP_FILE就是/var/run/utmp.在/usr/include/paths.h下 */ if (utmp_open(UTMP_FILE) == -1) { perror(UTMP_FILE); exit(1); } while((utbufp = utmp_next()) != ((struct utmp *)NULL)) show_info(utbufp); utmp_close(); return 0; } /* displays the contents of the utmp struct, display nothing if utmp has no user name */ void show_info(struct utmp *utbufp) { if (utbufp->ut_type != USER_PROCESS) return; printf("%-8.8s", utbufp->ut_user); /* The user name */ printf(" "); printf("%-8.8s", utbufp->ut_line); /* The tty name */ printf(" "); showtime(utbufp->ut_time); /* utime */ #ifdef SHOWHOST if (utbufp->ut_host[0] != '\0') printf(" (%s)", utbufp->ut_host); /* the host */ #endif printf("\n"); } /* displays time in a format */ void showtime(long timeval) { char *cp; cp = ctime(&timeval); /* convert time to string */ printf("%20.20s", cp+4); /* %12.12s prints a string 20 chars wide and LIMITS it to 20 chars. cp+4是为了把最前面的星期去掉 */ }实现缓冲的文件:utmplib.c
#include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <utmp.h> #define NRECS 16 #define NULLUT ((struct utmp *)NULL) #define UTSIZE ((sizeof(struct utmp))) static char utmpbuf[NRECS * UTSIZE]; /* storage */ static int num_recs; /* num stored */ static int cur_rec; /* next to go */ static int fd_utmp = -1; /* read from */ utmp_open(char *filename) { fd_utmp = open(filename, O_RDONLY); cur_rec = num_recs = 0; return fd_utmp; } struct utmp *utmp_next() { struct utmp *recp; if (fd_utmp == -1) return NULLUT; if (cur_rec == num_recs && utmp_reload() == 0) return NULLUT; recp = (struct utmp *)&utmpbuf[cur_rec * UTSIZE]; /* 依次获取下一个记录的地址 */ cur_rec++; return recp; } int utmp_reload() { int amt_read; /* 不是第一次读时都是从上次读到的位置继续读 */ amt_read = read(fd_utmp, utmpbuf, NRECS * UTSIZE); num_recs = amt_read/UTSIZE; /* 读到的真实个数 */ cur_rec = 0; /* 重置为0 */ return num_recs; } utmp_close() { if (fd_utmp != -1) /* 只有在打开之后才关闭 */ close(fd_utmp); }