编程实现who指令

实现who命令

编写who程序时,需要做两件事:

1.从文件(/var/run/utmp)中读取数据结构信息
2.以合适的形式将结构中的信息显示出来

第一步读取信息

从某个文件中读取数据,Linux系统提供了三个系统函数:open()、read()、close()。

open打开一个文件

open在Linux下的定义以及调用函数所需的头文件如下

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);


函数第一个参数pathname,是要打开的文件的路径名或者文件名。

第二个参数flags,表示打开文件的操作模式(有3种):只读(O_RDONLY)、只写(O_WRONLY)、可读可写(O_RDWR),调用此函数时,必须指定其中一种。还有其他可选模式,暂不做介绍。

第三个参数mode,表示设置文件访问权限的初始值,和用户掩码umask有关。此文暂时不用这个参数。

打开文件时,如果操作成功,内核会返回一个正整数的值,这个数值叫做文件描述符。如果内核检测到任务错误,这个系统调用会返回-1。

要对一个文件进行操作(读或者写),必须先打开文件。文件打开成功后,可以通过文件描述符对文件进行操作。

read()从文件读取数据

read在Linux下的定义以及调用函数所需的头文件如下:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);


函数第一参数fd,为文件描述符,由open函数返回。

第二个参数buf,存放读取数据的内存空间。

第三个参数count,希望读取的数据的个数。

如果读取成功,返回所读取数据的字节个数;否则,返回-1。

注意:最终读取的数据可能没有要求的多。例如,文件中剩余的数据少于要求读取的个数,则程序只能读取文件中剩余的数据个数。当读到文件末尾时,函数会返回0。

close关闭文件

clsoe在Linux下的定义以及调用函数所需的头文件如下:

#include <unistd.h>

int close(int fd);


close 这个系统函数会关闭已经打开的文件,fd为open()函数打开文件返回的描述符。如果关闭出错,函数返回-1。关闭成功,则返回0。

对文件的操作完成后,需要关闭文件,以减少内存资源占用。

第二步显示信息

通过printf函数利用定宽度的格式显示utmp记录信息。

第三步代码实现

#include<stdio.h>
#include<utmp.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>

#define SHOWHOST

void show_info(struct utmp *utbufp);

int main()
{
    struct utmp current_record;
    int utmpfd;
    int reclen = sizeof(current_record);

    if((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1)
    {
        perror(UTMP_FILE);
        exit(1);
    }
    while(read(utmpfd, &current_record, reclen) == reclen)
    {
        show_info(&current_record);
    }
    close(utmpfd);

    return 0;
}

// 显示信息
void show_info(struct utmp *utbufp)
{
    printf("%-8.8s", utbufp->ut_name);
    printf(" ");
    printf("%-8.8s", utbufp->ut_line);
    printf("%10d", utbufp->ut_time);
    printf(" ");

#ifdef SHOWHOST
    printf("(%s)", utbufp->ut_host);
#endif

    printf("\n");
}


编译
$gcc who1.c -o who1
运行结果如下

$./who1
reboot ~ 1635728912 (4.15.0-161-generic)
runlevel ~ 1635729058 (4.15.0-161-generic)
user :0 1635729148 (:0)
test pts/2 1635763291 (192.168.0.104)

将上述输出结果与系统who命令输出做对比:

$ who
user :0 2021-11-01 09:12 (:0)
test pts/2 2021-11-01 18:41 (192.168.0.104)

posted @ 2023-10-11 09:35  入林寻梨花白  阅读(6)  评论(0编辑  收藏  举报