最近在一邊學習c一邊看《unix-linux程式設計實踐教程》。這本書在去年就已經看過一遍了,其中的例子當時也跟著編過。本來是最近是準備看《unix環境高階程式設計》這本書的,突然發現《unix-linux程式設計實踐教程》的內容都已忘的差不多了,就決定先再把它看一遍。
既然要拿起來在學,就好好學一下吧。決定自己先不看書,自己動手先再重寫一遍。根據書中的套路(這個現在居然還記得):1、這個程式能幹嘛?2、這個程式是如何實現的?3、自己動手寫乙個。在這幾個過程中終於是體會到在linux底下寫程式的方便了,主要是依靠man。
程式涉及到的主要有utmp結構體:
struct utmp 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
just ut_addr_v6[0] */
char __unused[20]; /* reserved for future use */
};
#define utmp_file _path_utmp
繼續用grep命令查詢發現_path_utmp 是在這裡定義的
/usr/include/paths.h:64:#define _path_utmp "/var/run/utmp"
到現在應該是可以肯定utmp結構體書儲存在/var/run/utmp 這個檔案中的了。
為了從檔案中讀取資料,就需要了解幾個同檔案讀取有關的函式了。我們需要的操作應該是開啟utmp_file,讀取其中的資料,最後關閉這個檔案。作為乙個c語言初學者,一開始想到的可能是fopen、fscanf和fclose這三個函式。但是fscanf無法讀取乙個資料結構的資料。很自然的就會用到open、read和close這幾個系統呼叫了。下面是這幾個函式的基本資訊:
int open(const char *pathname, int flags);
ssize_t read(int fd, void *buf, size_t count);
int close(int fd);
其中read是根據位元組數來讀取檔案中內容的,我們當然可以獲取乙個結構體的大小。有了以上的這些內容就可以開始寫who程式了:
#include #include #include #include #include #define utmp_size (sizeof(struct utmp))
void inline disuinfo(struct utmp uinfo)
int main(int argc, char *argv)
while (utmp_size == read(fd, uinfo, utmp_size))
}close(fd); //don't forget close the fd
free(uinfo);//don't forget to free the memory
return 0;
}
將這個程式和之前我寫的程式進行比較時有兩點是需要總結的:
1、在之前寫的程式中指向結構體utmp的指標uinfo我沒有初始化就直接使用了。omg,程式跑起來當然是沒什麼問題的,但是肯定是修改系統中其他地方的記憶體了(跑了這麼多次系統居然沒崩潰…)。這就是c語言不強制要求指標使用之前必須初始化,並且自己不小心的結果吧。下面只將uinfo指標的值初始化為null,看執行程式有什麼結果。
struct utmp *uinfo = null //只將上面的程式修改這一行
如果這麼改的話main函式一進去就退出了,也沒報錯感覺到有點奇怪。這個問題暫且記下以後找個時間專門研究一下。
2、在之前的程式中我寫了乙個函式,現在看能沒有任何作用。現在我也看不出有什麼作用了,主要還是因為沒寫好注釋的緣故。以後再寫程式不能在忽視注釋了。
在寫這個程式的過程中有幾點需要總結的:
1、在寫的過程中居然不大確定printf格式符 %m.nx 中m、n的含義了。在這裡在寫一遍:a、對於基本型別:m指定了要顯示的最少字元數。如果要顯示的數值所需的字元數少於m,那麼值在顯示寬度內是右對齊的。如果要顯示的值所需的字元數多於m,那麼顯示寬度會自動擴充套件為所需的尺寸。n表示小數點後的位數。b、m的含義同基本型別相同,n表示只顯示字串的前n個字元。
2、關於時間的顯示轉換,我最開始用的是ctime、後來用gmtime最後在用localtime的。ctime的返回值是乙個字串,其格式是:"wed jun 30 21:49:08 1993\n";gmtime和localtime的返回值都是乙個tm結構體(可以去查man)。不同的是localtime的tm_hour會加上你所在的時區。這兩個函式的年份你要加上1900,月份是從0開始算的要正常顯示的話得加上1.
Linux基礎命令 who
常用工具命令 who命令是顯示目前登入系統的使用者資訊。執行who命令可得知目前有那些使用者登入系統,單獨執行who命令會列出登入帳號,使用的終端機,登入時間以及從何處登入或正在使用哪個x顯示器。who 選項 引數 選項 h或 heading 顯示各字段的標題資訊列 i或 u或 idle 顯示閒置時...
Linux命令(20) who命令
who命令 功能說明 who命令顯示目前登入到系統的使用者,顯示的資料報含了使用者 id 使用的終端機 從哪邊連上來的 上線時間 呆滯時間 cpu 使用量 動作等等。用法如下 who option file who命令的一般輸出格式 名稱 狀態 終端 時間 活動 程序標識 主機名 命令引數 選項含義...
Linux下who命令的實現
linux系統的正常運作需要使用大量與系統有關的資料檔案,例如,口令檔案 etc passwd和組檔案 etc group就是經常被多個程式頻繁使用的兩個檔案。使用者每次登陸 linux系統,以及每次執行ls l命令時都要使用口令檔案。本實驗中的程式就是這樣乙個需要呼叫系統資料檔案的程式,只不過呼叫...