通過串行終端登錄至系統和經由網絡登錄至系統兩者之間的主要(物理上的)區別是:通過網絡登錄時,終端和計算機之間的連接不是點對點連接。在這種情況下,login只是一種可用的服務,這與其他網絡服務(例如FTP或SMTP)的性質相同。
在終端登錄中,init知道哪些終端設備可用來進行登錄,并為每個設備生成一個getty進程。但是在網絡登錄情況下,所有登錄都經由內核的網絡接口驅動程序(如以太網驅動程序),事先并不知道將會有多少這樣的登錄。我們不是使一個進程等待每個可能的登錄,而是必須等待一個網絡連接請求的到達。
為使同一軟件即能處理終端login,又能處理網絡login,系統使用了一種稱為偽終端(pseudo terminal)的軟件驅動程序,它仿真串行終端的運行行為,并將終端操作映射為網絡操作,反之亦然。
1、BSD網絡登錄在BSD中,有一個稱為inetd的進程(有時稱之為因特網超級服務器),它等待大多數網絡連接。
作為系統啟動的一部分,init調用一個shell,使其執行shell腳本/etc/rc。由此shell腳本啟動一個守護進程inetd。一旦此shell腳本終止,inetd的父進程就變成init。inetd等待TCP/ip連接請求到達主機,而當一個連接請求到達時,它執行一次fork,然后生成的子進程執行適當的程序。
我們假定到達了一個針對TELNET服務進程的TCP連接請求。TLENET是使用TCP協議的遠程登錄應用程序。在另一臺主機(它通過某種形式的網絡與服務進程的主機相連接)上的用戶,或在同一臺主機上的用戶啟動TELNET客戶端進程,由此啟動登錄過程:
telnet hostname
該客戶進程打開一個到hostname主機的TCP連接,在hostname主機上啟動的程序被稱為TELNET服務進程。然后,客戶進程和服務進程之間使用TELNET應用協議通過TCP連接交換數據。所發生的是啟動客戶進程的用戶現在登錄到了服務進程所在的主機。(自然,用戶需要在服務進程主機上有一個有效的賬號)。
然后,telnetd進程(TELNET服務進程)打開一個偽終端設備,并用fork分成兩個進程。父進程處理通信網絡連接的通信,子進程則執行login程序。父、子進程通過偽終端相連接。在調用exec之前,子進程使其文件描述符0、1、2與偽終端相連。如果登錄正確,login就執行與終端登錄中同樣的步驟:更改當前工作目錄為起始目錄,設置登錄用戶的組ID和用戶ID,以及登錄用戶的初始環境。然后login調用exec將其自身替換為登錄用戶的登錄shell。
需要理解的重點是:當通過終端或網絡登錄時,我們得到一個登錄shell,其標準輸入、輸出和標準出錯連接到一個終端設備或者偽終端設備上。這一登錄shell是POSIX.1會話的開始,而此終端或偽終端則是會話的控制終端。
2、linux網絡登錄除了使用擴展的因特網服務守護進程xinetd替代inetd進程外,Linux網絡登錄的其他方面與BSD相同。xinetd進程對它所啟動的各種服務的控制比inetd提供的更加精細。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答