1.who命令的作用是什么?
使用who命令能查看正在使用当前系统的用户:
who命令的具体用法可以通过man who命令查看。
2.who命令的原理是什么?
上图是通过man who命令得到的who命令的帮助手册,它的小节编号是1,。不同小节编号是各种不同的帮助信息。
注意:ubuntu下已登录用户的信息是放在/var/run/utmp这个文件下
带有-k选项的man命令可以根据关键字搜索联机帮助,这属于一种模糊搜索。使用man -k utmp会找到很多和utmp相关的帮助页:
上图中红色方框那一行可能是我们所需要的,其中括号5表示小节的编号,说明该帮助是位于第5节,通过以下命令来查看:
man 4 utmp
从上图的红色大方框可以知道,utmp文件是a sequence of utmp structures,即该文件保存的是一序列的utmp结构体(也就是结构体数组),还知道utmp类型的结构体在utmp.h文件中声明的形式和utmp文件最下面utmp类型的结构体声明的是一样的。
注意:Unix/Linux系统中,大多数头文件都放在/usr/include这个目录里。当C语言编译器发现如#include <stdio.h>这样的头文件语句的时候,它会到/usr/include中查找相应的头文件。
上图是在utmp文件中截取的utmp结构体的部分定义,其中ut_line保存设备名,即用户的终端类型;ut_user保存登录名;ut_host保存用户用于登录的远程计算机的名字。而用户的登录时间被保存在ut_tv结构体中:
其它utmp结构体的成员没有被who命令用到。
3.who命令的工作原理是什么?
每个登录的用户的信息都被utmp文件中的一个结构体所保存,who命令通过读取该文件来获得用户登录信息。
3.编写自己的who命令
基本想法就是把utmp文件中的结构体一个个读出来并在终端显示。
其中最有可能的是read(2),所以进一步查看read(2)的帮助:
使用open, read, close这三个函数:
(1)open函数:打开文件
这个系统调用(系统调用也是个函数,是由内核提供的服务)在进程和文件之间建立了一条连接,这个连接用文件描述符(fd)标识,它就像一条由进程通向内核的管道:
open函数的基本用法:
使用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函数用法:
read函数向内核发出请求,请求从文件描述符fd所标识的文件中读取qty个字节的数据。然后,这些数据被放到buf所在的内存空间。若读取成功,则返回的numread表示读取的字节数目。若qty为1000,而文件长度只有500个字节,那么返回的numread数值就是500。
(3)close函数:关闭已打开的文件(不关闭的话其它进程不能写这个文件)