who命令的基本实现(上)

1.who命令的作用是什么?

使用who命令能查看正在使用当前系统的用户:

who命令的基本实现(上)_第1张图片

who命令的具体用法可以通过man who命令查看。

2.who命令的原理是什么?

who命令的基本实现(上)_第2张图片

上图是通过man who命令得到的who命令的帮助手册,它的小节编号是1,。不同小节编号是各种不同的帮助信息。

who命令的基本实现(上)_第3张图片

注意:ubuntu下已登录用户的信息是放在/var/run/utmp这个文件下

带有-k选项的man命令可以根据关键字搜索联机帮助,这属于一种模糊搜索。使用man -k utmp会找到很多和utmp相关的帮助页:

who命令的基本实现(上)_第4张图片

上图中红色方框那一行可能是我们所需要的,其中括号5表示小节的编号,说明该帮助是位于第5节,通过以下命令来查看:

man 4 utmp

who命令的基本实现(上)_第5张图片

从上图的红色大方框可以知道,utmp文件是a sequence of utmp structures,即该文件保存的是一序列的utmp结构体(也就是结构体数组),还知道utmp类型的结构体在utmp.h文件中声明的形式和utmp文件最下面utmp类型的结构体声明的是一样的。

注意:Unix/Linux系统中,大多数头文件都放在/usr/include这个目录里。当C语言编译器发现如#include 这样的头文件语句的时候,它会到/usr/include中查找相应的头文件。

who命令的基本实现(上)_第6张图片

上图是在utmp文件中截取的utmp结构体的部分定义,其中ut_line保存设备名,即用户的终端类型;ut_user保存登录名;ut_host保存用户用于登录的远程计算机的名字。而用户的登录时间被保存在ut_tv结构体中:

who命令的基本实现(上)_第7张图片

其它utmp结构体的成员没有被who命令用到。

3.who命令的工作原理是什么?

每个登录的用户的信息都被utmp文件中的一个结构体所保存,who命令通过读取该文件来获得用户登录信息。

who命令的基本实现(上)_第8张图片

3.编写自己的who命令

基本想法就是把utmp文件中的结构体一个个读出来并在终端显示。

who命令的基本实现(上)_第9张图片

who命令的基本实现(上)_第10张图片

其中最有可能的是read(2),所以进一步查看read(2)的帮助:

who命令的基本实现(上)_第11张图片使用open, read, close这三个函数:

(1)open函数:打开文件

这个系统调用(系统调用也是个函数,是由内核提供的服务)在进程和文件之间建立了一条连接,这个连接用文件描述符(fd)标识,它就像一条由进程通向内核的管道:

who命令的基本实现(上)_第12张图片

open函数的基本用法:

who命令的基本实现(上)_第13张图片

使用open打开文件需要指定:文件名和打开模式。O_RDONLY, O_WRONLY, O_RDWR这三种打开模式分别对应于只读、只写、可读可写。O_RDONLY, O_WRONLY, O_RDWR在头文件/usr/include/fcntl.h中有定义。

使用open打开文件时,出现错误的类型是各种各样的,如:要打开的文件不存在。即使文件存在,也可能因为权限不够而无法打开,或者是无权访问文件所在的目录open的联机帮助中列出了各种可能的错误。

一个文件是允许同时被多个进程访问的,要不然两个用户就无法同时使用who命令了。

文件被成功打开后,会返回一个正整数的值,该值就叫做文件描述符(file descriptor),文件描述符就是用来惟一标识进程和文件之间的连接的。如果同时打开好几个文件,它们所对应的文件描述符是不同的,如果将一个文件打开多次,对应的文件描述符也不相同。

(2)read函数:从文件中读取数据

read函数用法:

who命令的基本实现(上)_第14张图片

read函数向内核发出请求,请求从文件描述符fd所标识的文件中读取qty个字节的数据。然后,这些数据被放到buf所在的内存空间。若读取成功,则返回的numread表示读取的字节数目。若qty为1000,而文件长度只有500个字节,那么返回的numread数值就是500。

(3)close函数:关闭已打开的文件(不关闭的话其它进程不能写这个文件)

who命令的基本实现(上)_第15张图片


你可能感兴趣的:(UnixLinux编程实践)