1. 程式人生 > >who命令的基本實現(上)

who命令的基本實現(上)

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函式:關閉已開啟的檔案(不關閉的話其它程序不能寫這個檔案)