linux系统编程(一):who命令编写(open、read、close)

1、who命令的作用


通过在terminal调用who命令,我们可以看到现在登录在linux系统的用户。用户登录信息的数据结构定义在/usr/include/utmp.h。

wall pts/4        2019-03-07 09:09 (10.165.33.169)
shen pts/16       2019-03-05 10:04 (10.165.39.163)
li   pts/25       2019-03-07 10:26 (10.165.21.93)

要完成who命令的功能实现,我们需要用到以下几个系统调用。

open:打开一个文件

read:读取文件中一定长度的数据

close:关闭文件

2、需要使用的系统调用


2.1 打开一个文件 open:

open系统调用在进程和文件之间建立一个连接,这个连接被称为文件描述符,它就像一个由进程通向内核的管道。

 open
目标打开一个文件
头文件#include<fcntl.h>
函数原型int fd = open(char * name, int how)
参数

name 文件名

how   打开方式(O_RDONLY,O_WRONLY,O_RDWR)

返回值

-1      打开失败

int     成功返回

 

如果文件成功打开,内核会返回一个正整数的值,这个数值就是文件描述符。如果打开多个文件,它们对应的描述符是不同的。如果将一个文件打开多次,它们的文件描述符也是不同的。

2.2 从文件中读取数据 read:

read系统调用请求内核从fd所指定的文件中读取qty个字节的数据,并存放到buf所指向的内存空间中。如果读取成功返回所读取的字节数目,否则返回-1.

 read
目标将数据读取到缓冲区
头文件#include<unistd.h>
函数原型ssize_t numread = read(int fd, void* buf, size_t qty)
参数

fd     文件描述符

buf   用来存放数据的缓冲区

qty   要读取的字节数

返回值

-1      遇到错误

int     成功返回

2.3 关闭文件 close:

close系统调用会关闭进程和文件fd之间的连接,如果关闭的过程中发生错误,会返回-1。成功返回0.

 close
目标关闭一个文件
头文件#include<unistd.h>
函数原型

 int result  = close(int fd)

参数

fd     文件描述符

返回值

-1      遇到错误

int     成功返回

3、程序编写


#include <stdio.h>
#include <unistd.h>
#include <utmp.h>
#include <fcntl.h>
#include <time.h>

void showtime(long);
void show_info(struct utmp*);

void who(){
    struct utmp utbuf;
    int utmpfd;
    
    if((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1){   // UTMP_FILE记录了文件位置
        perror(UTMP_FILE);    
        _exit(1);
    }
    
    while(read(utmpfd, &utbuf, sizeof(struct utmp)) == sizeof(struct utmp)){
        show_info(&utbuf);
    }
    close(utmpfd);
}

void show_info(struct utmp* utbuf){
    if(utbuf->ut_type != USER_PROCESS)    // USER_PROCESS用来标示活跃用户
        return;
    printf("% -8.8s", utbuf->ut_name);
    printf(" ");
    printf("% -8.8s", utbuf->ut_line);
    printf(" ");
    showtime(utbuf->ut_time);
#ifdef SHOWHOST
    if(utbuf->ut_host[0] != '\0')
        printf("(%s)", ufbuf->ut_host);
#endif
    printf("\n");
}

void showtime(long timeval){
    char* cp;
    cp = ctime(&timeval);    // 对时间进行输出格式转换
    printf("%12.12s", cp+4);
}

运行结果为:

wall pts/4    Mar  7 09:09
shen pts/16   Mar  5 10:04
li   pts/25   Mar  7 10:26

UTMP_FILE是包含登录用户的信息的文件。但是UTMP_FILE中还包含许多非活跃的用户登录信息,utmp使用USER_PROCESS用于指明那些活跃的用户登录信息。t_time是1970年1月1日0时距离现在时刻的时间差,并不是我们想要的标准时间格式。使用time下的ctime函数,可以将其转化为标准时间。ctime的输出格式为Wed Jun 30 21:49:08 1992 \n 将指针加4跳过星期。

整个程序十分简单。我们打开UTMP_FILE文件,然后按照大小utmp结构体的大小依次读取每条登录用户的信息,直到读到文件末尾,将文件关闭。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值