linux下自实现简易who命令

/*
    命令who可输出,当前登录到主机的用户名、终端、登录时间
*/
#include <stdio.h>
#include <utmp.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

int main(int argc, char* argv[])
{
    int fp;
    struct tm *temp;
    struct utmp buf;
    time_t t1;
    char buf1[50];
    int n = sizeof(struct utmp);
    //访问UTMP_FILE文件,即/var/run/utmp文件
    fp = open(UTMP_FILE, O_RDONLY);
    //fp = open("/var/run/utmp", O_RDONLY);
    if (fp == -1) {
        perror("/var/run/umtp");
        exit(1);
    }
    while (read(fp, &buf, n) == n) 
        if (buf.ut_type == 7) {
            //将按秒时间转换为time_t格式时间
            t1 = buf.ut_tv.tv_sec;
            //输出适当格式
            temp = localtime(&t1);
            strftime(buf1, 50, "%F %R", temp);
            printf("%s\t%s\t%s\n", buf.ut_user, buf.ut_line, buf1);
            //printf("%s\t%s\t%s", buf.ut_user, buf.ut_line, ctime(&t1));
        }
    close(fp);
    
}
/*
    此版本采用缓存机制,read_record函数,一次从文件中读取多个结构单元
*/
#include <stdio.h>
#include <utmp.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

#define NUM 16
int read_record(int fp, char* buf, int num)
{
    int n;
    n = read(fp, buf, num*sizeof(struct utmp));
    return n/sizeof(struct utmp);
}

int main(int argc, char* argv[])
{
    int fp;
    struct tm *temp;
    struct utmp *buf;
    time_t t1;
    char buf2[NUM*sizeof(struct utmp)];
    char buf1[50];
    int count, current;
    
    int n = sizeof(struct utmp);
    fp = open(UTMP_FILE, O_RDONLY);
    if (fp == -1) {
        perror("/var/run/umtp");
        exit(1);
    }
    while ((count =read_record(fp, buf2, NUM)) != 0) {
        current = 0;
        while (count--) {
            buf = (struct utmp*)buf2+current*sizeof(struct utmp);
            if (buf->ut_type == 7) {
                t1 = buf->ut_tv.tv_sec;
                temp = localtime(&t1);
                strftime(buf1, 50, "%F %R", temp);
                printf("%s\t%s\t%s\n", buf->ut_user, buf->ut_line, buf1);
            }
            current++;
        }
    }
    close(fp);
    
}
/*
    模拟用户退出时,修改utmp文件
    格式 logout username
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <utmp.h>
#include <time.h>
int main(int argc, char* argv[])
{
    int fd;
    struct utmp buf;
    int n;
    
    n = sizeof(struct utmp);
    if (argc == 1) {
        fprintf(stderr, "logout:missing file operand");
        exit(1);
    }
    fd = open("utmp", O_RDWR);
    if (fd == -1) {
        perror("open failed");
        exit(1);
    }
    while (read(fd, &buf, n) == n) 
        if (buf.ut_type == 7 && (!strcmp(buf.ut_line, argv[1]))) {
            buf.ut_type = DEAD_PROCESS;
            if (time(&buf.ut_time) == -1) {
                perror("time update");
                exit(1);
            }
            if (lseek(fd, -n, SEEK_CUR) == -1) {
                perror("lseek error");
                exit(1);
            }
            if (write(fd, &buf, n) != n) {
                perror("write error");
                exit(1);
            }
            break;
        }
    close(fd);
    return 0;    
}

总结:

时间处理函数,localtime和gtime,localtime会考虑时区,gtime则不会,gtime可能导致时间晚几个(8个)小时。

你可能感兴趣的:(linux下自实现简易who命令)