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