who命令的实现

来源:互联网 发布:海参偶尔吃 知乎 编辑:程序博客网 时间:2024/04/29 15:16
#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);}