1. 4.3+BSD終端登錄
系統(tǒng)管理員創(chuàng)建一個(gè)通常名為/etc/ttys的文件,其中,每個(gè)終端設(shè)備有一行,每一行說明設(shè)備名和傳到getty程序的參數(shù),這些參數(shù)說明了終端的波特率。當(dāng)系統(tǒng)bootstrap時(shí)內(nèi)核創(chuàng)建進(jìn)程ID 1,也就是init進(jìn)程。init進(jìn)程使系統(tǒng)進(jìn)入多用戶狀態(tài)。init讀文件/etc/ttys,對(duì)每一個(gè)允許登錄的終端設(shè)備,init調(diào)用一次fork,它所生成的子進(jìn)程則執(zhí)行程序getty。這種情況見下圖:
圖中每個(gè)進(jìn)程的實(shí)際用戶ID和有效用戶ID都是0(即都有root權(quán)限)。init以空環(huán)境執(zhí)行g(shù)etty程序。
getty對(duì)終端設(shè)備調(diào)用open函數(shù),以讀、寫方式將終端打開。如果設(shè)備是調(diào)制解調(diào)器,則open可能會(huì)在設(shè)備驅(qū)動(dòng)程序中滯留,直到用戶撥號(hào)調(diào)制解調(diào)器,并且線路被接通。一旦設(shè)備被打開,則文件描述符0、1、2就被設(shè)置到該設(shè)備。然后getty輸出"login:"之類的信息,并等待用戶鍵入用戶名。如果終端支持多種速度,則getty可以測(cè)試特殊字符以便適當(dāng)?shù)馗慕K端速度(波特率)。
當(dāng)用戶鍵入用戶名后,getty就完成了,然后它以類似于下列的方式調(diào)用login程序:
execle("/usr/bin/login", "login", "-p" username, (char *) 0, envp);
(在gettytab文件中可能會(huì)有一些選擇使其調(diào)用其他程序,但系統(tǒng)默認(rèn)是login程序)。init以一個(gè)空環(huán)境調(diào)用getty。getty以終端名(例如TERM=foo,其中終端foo的類型取自gettytab文件)和在gettytab中的環(huán)境字符串為login創(chuàng)建一個(gè)環(huán)境(envp參數(shù))。-p標(biāo)志通知login保留傳給它的環(huán)境,也可以將其他環(huán)境字符串加到該環(huán)境中,但是不要替換它。下圖顯示了login剛被調(diào)用后這些進(jìn)程的狀態(tài)。
因?yàn)樽畛醯膇nit進(jìn)程具有root權(quán)限,所以圖中所有進(jìn)程都有root權(quán)限。圖中底部三個(gè)進(jìn)程的進(jìn)程ID相同,因?yàn)檫M(jìn)程ID不會(huì)因執(zhí)行exec而改變。并且除了最初的init進(jìn)程,所有的進(jìn)程均有一個(gè)父進(jìn)程ID。
login能處理多項(xiàng)工作。因?yàn)樗玫搅擞脩裘?,所以能調(diào)用getpwnam取得相應(yīng)用戶的口令文件登陸項(xiàng)。然后調(diào)用getpass以顯示提示"Password:"接著讀用戶鍵入的口令。它調(diào)用crypt將用戶鍵入的口令加密,并與該用戶口令文件中登陸項(xiàng)的pw_passwd字段相比較。如果用戶幾次鍵入的口令都無效,則login以參數(shù)1調(diào)用exit表示登錄過程失敗。父進(jìn)程(init)了解到子進(jìn)程的終止情況后,將再次調(diào)用fork,其后又跟著執(zhí)行g(shù)etty,對(duì)此終端重復(fù)上述過程。
如果用戶正確登錄,login就將當(dāng)前工作目錄更改為用戶的home目錄。它也調(diào)用chown改變?cè)摻K端的所有權(quán),使該用戶成為所有者和組所有