who命令的实现

#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);
}


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