博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现who
阅读量:6717 次
发布时间:2019-06-25

本文共 3921 字,大约阅读时间需要 13 分钟。

还是按照问题一步一步的展开

1. who能做什么

2. who怎样工作的

3. 如何实现who

 

1. who能做什么

  在linux中who就是显示谁在使用系统。

2. who怎样工作的:

  直接man who,可以看到如下的描述

If FILE is not specified, use /var/run/utmp.  /var/log/wtmp as FILE  is       common.   If  ARG1  ARG2  given, -m presumed: 'am i' or 'mom likes' are       usual.

可以看到who是从utmp获取信息的, 收索联机帮助 寻找utmp

man -k  utmp

utmp (5)             - login records

直接man 5 utmp

The  file  is  a  sequence  of  utmp structures, declared as follows in       
(note that this is only one of several definitions around; details depend on the version of libc):... ...struct utmp { short ut_type; /* Type of record */ pid_t ut_pid; /* PID of login process */ char ut_line[UT_LINESIZE]; /* Device name of tty - "/dev/" */ char ut_id[4]; /* Terminal name suffix, or inittab(5) ID */ char ut_user[UT_NAMESIZE]; /* Username */ char ut_host[UT_HOSTSIZE]; /* Hostname for remote login, or kernel version for run-level messages */ struct exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS; not used by Linux init (1 */ /* The ut_session and ut_tv fields must be the same size when compiled 32- and 64-bit. This allows data files and shared memory to be shared between 32- and 64-bit applications. */ #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 int32_t ut_session; /* Session ID (getsid(2)), used for windowing */ struct { int32_t tv_sec; /* Seconds */ int32_t tv_usec; /* Microseconds */ } ut_tv; /* Time entry was made */ #else long ut_session; /* Session ID */ struct timeval ut_tv; /* Time entry was made */ #endif int32_t ut_addr_v6[4]; /* Internet address of remote host; IPv4 address uses

可以看到数据都放在utmp中.继续往下可以看到文件的位置信息

FILES       /var/run/utmp       /var/log/wtmp

 

3. 如何实现who

到这里基本上就可以开始用伪代码编写了:

伪代码如下:

  打开utmp

  读取用户记录

  显示用户记录

  关闭utmp

 

因为这次读取是直接读取数据块,一行一行(fgets)和一个字符一个字符(getchar)的读取都不合适,所以选用read函数。

第一步自然是打开utmp,这个文件的路径在哪里呢, 头文件一般都是放在/USR/INCLUDE/下的,果然在头文件中找到路径的定义:

/* Compatibility names for the strings of the canonical file names.  */#define UTMP_FILE        _PATH_UTMP#define UTMP_FILENAME    _PATH_UTMP#define WTMP_FILE        _PATH_WTMP#define WTMP_FILENAME    _PATH_WTMP

可以随便选一个,我们就选第一个作为路径。按照伪代码编写如下

#include 
#include
#include
#include
void ShowRecord(struct utmp*);int main(int ac, char* av[]){ struct utmp record; int recordSize = sizeof(record); int utmpFd; //打开utmp utmpFd = open(UTMP_FILE,O_RDONLY); if(-1 == utmpFd) { perror(UTMP_FILE); return -1; } //读取用户记录 while (read(utmpFd,&record,recordSize) == recordSize) { //显示用户记录 ShowRecord(&record); } //关闭utmp close(utmpFd); return 0;}void ShowRecord(struct utmp* pRecord){ printf("%-8.8s\n",pRecord->ut_name); printf("%-8.8s\n",pRecord->ut_line); printf("%-8.8d\n",pRecord->ut_time); printf("\n");}

运行结果:

jerry@ubuntu:~/work/chapter01$ ./test reboot  ~       1492427813LOGIN   tty1    1492427835runlevel~       1492427839jerry   tty7    1492427909jerry@ubuntu:~/work/chapter01$

数据读出来了,就是显示格式需要再调整。继续进行优化如下问题,今天就到这里

 1. 格式排版问题

 2. 时间显示问题

 

转载于:https://www.cnblogs.com/XiangWei1/p/6724502.html

你可能感兴趣的文章
oracle中修改表名
查看>>
PhpStorm下Laravel代码智能提示
查看>>
IntelliJ IDEA中运行Tomcat报内存溢出(java.lang.OutOfMemoryError: PermGen space)
查看>>
转】 Kafka文件存储机制那些事
查看>>
jquery怎么在点击li标签之后添加一个在class,点击下一个li时删除上一个class?...
查看>>
在Docker中运行web应用
查看>>
spring boot 框架 启动更新项目,以及生成 "实体_"文件
查看>>
android启动模式
查看>>
arcgis api for js入门开发系列七图层控制
查看>>
JavaScript EventLoop
查看>>
新安装个Myeclipse,导入以前做的程序后程序里好多错,提示The import java.util cannot be resolved...
查看>>
第六篇:GPU 并行优化的几种典型策略
查看>>
Cronolog 分割 Tomcat8 Catalina.out日志 (转)
查看>>
Linux Platform驱动模型(二) _驱动方法
查看>>
商城系统购物车功能分析实现
查看>>
Java之Builder模式(并用OC实现了这种模式)
查看>>
module_loader.py
查看>>
SFINAE 模板替换失败而非报错的应用
查看>>
Java 反射详解
查看>>
mySQL中replace的用法
查看>>