自己动手写shell命令之who
思路:在unix系统中有一个名为utmp的文件,里面存着当前登录到系统中用户的信息。utmp这个文件里面保存的是结构数组,数组元素是utmp类型的结构。实现who命令,只要依次从utmp文件中读出utmp类型的结构体,然后通过合适的方式将它显示出来即可。如果每一次只从文件里面读一个结构体数据,那么每一个结构体都要进行依次系统调用。而又因为系统调用比较耗时(涉及到用户态到核心态的切换),所以这样会造成程序低效。我们使用缓冲技术,每次从文件中读若干结构体数据到内存中,当这些数据都已经显示在终端后,我们再从文件中读数据,这样能有效的提高程序的效率。
代码:
utmplib.c
#include <fcntl.h> #include <sys/types.h> #include <utmp.h> #define NRECS 16 #define UTSIZE (sizeof(struct utmp)) #define UTNULL ((struct utmp *)NULL) static char utmp_buffer[NRECS * UTSIZE]; static int utmp_num; static int cur_num; static int utmp_fd = -1; int utmp_open(char * filename) { utmp_fd = open(filename,O_RDONLY); cur_num = 0; utmp_num = 0; return utmp_fd; } struct utmp * utmp_next() { struct utmp * next; if(utmp_fd == -1) return UTNULL; if(cur_num == utmp_num && utmp_reload() == 0) return UTNULL; next = (struct utmp *)&utmp_buffer[UTSIZE*cur_num]; cur_num++; return next; } int utmp_reload() { int len = read(utmp_fd,utmp_buffer,UTSIZE*NRECS); utmp_num = len / UTSIZE; cur_num = 0; return utmp_num; } void utmp_close() { if(utmp_fd != -1) close(utmp_fd);
#include "utmplib.c" #include <sys/types.h> #include <utmp.h> #include <fcntl.h> #include <time.h> void show_info(struct utmp *); void showtime(time_t); int main() { printf("%s",UTMP_FILE); struct utmp * utmp_buffer; int fd; if((fd = utmp_open(UTMP_FILE)) == -1) return -1; //utmp_reload(); while((utmp_buffer = utmp_next()) != UTNULL) show_info(utmp_buffer); utmp_close(); return 0; } void show_info(struct utmp * buffer) { if(buffer->ut_type != USER_PROCESS)//utmp结构中有一个ut_type成员,当其为USER_PROCESS时,表明这是一个已经登陆的用户 return; printf("%-8.8s",buffer->ut_name); printf(" "); printf("%-8.8s",buffer->ut_line); printf(" "); showtime(buffer->ut_time); #ifdef SHOWHOST if(buffer->ut_host[0] != '\0') printf("(%s)",buffer->ut_host); #endif printf("\n"); } void showtime(time_t time) { char * cp; cp = ctime(&time); printf("%12.12s",cp+4); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。