根目錄如何用於解析絕對路徑名?
APUE 說
每個程序還有一個根目錄,用於解析絕對路徑名。可以使用 chroot 函式更改此根目錄。
我認為只有相對路徑名需要解析。所以我想知道
- 絕對路徑名的解析是什麼意思?
- 如何
chroot
使用根目錄來解析絕對路徑名?謝謝。
所有路徑名都需要解析。顯然,程序將路徑名作為系統呼叫的參數傳遞給核心,例如:
creat
或open
,link
或rename
,unlink
或rmdir
,chmod
或chown
,chdir
或chroot
,execve
,等等考慮一個看起來像這樣的路徑名
…
a
/
b
/
c
核心對此的解釋方式是:
開始(文件系統中的某處),
查找名為
a
1的目錄。如果未找到,則返回錯誤。
如果找到,則在該目錄中搜尋名為
b
.如果未找到,則返回錯誤。如果找到,則在該目錄中搜尋名為2
的目錄條目。 如果未找到,則返回錯誤3。 如果找到,則返回該 inode。
c
注意路徑名開頭和算法第一行的混淆。很簡單:如果路徑名以斜杠開頭(即,它是“絕對路徑名”,例如
/a/b/c
, ,a/b/c
),搜尋從程序的目前工作目錄開始。您可能會問“這是如何實現的?” 嗯,當然,核心維護著很多關於每個程序的資訊,包括
- PID、PPID 和各種程序組標識符,
- 真實、有效、保存的 UID 和 GID,以及補充 GID 列表,
- 打開文件,
- 信號配置,
和更多。我遺漏了很多東西,因為它們與這個問題無關。我省略了環境變數,因為它們不是由核心維護的;它們由使用者空間程序維護。核心所做的只是支持一種將環境變數從一個程序傳遞到另一個程序的機制
execve
。出於戲劇性目的,我在上面的列表中遺漏了兩件事:
- 程序的根目錄,以及
- 目前工作目錄
這些是指向 inode 的指針。我希望每個人都了解程序的目前工作目錄是如何設置的——程序呼叫
chdir
,將路徑名作為參數傳遞給它;核心按照上述過程解釋路徑名(將其解析為 inode),並在成功後將目前目錄指針設置為指向該 inode。程序的根目錄的設置方式相同,除了
chroot
系統呼叫。(請注意,在任何一種情況下,如果路徑名參數以 開頭,則路徑名解析從呼叫系統呼叫時生效
/
的程序的根目錄開始 。)一些例子:
如果您的目前目錄是
/home/tim
(並且您的程序根目錄是文件系統根目錄),那麼
- 如果你訪問
/etc/services
,你會得到/etc/services
,- 如果你訪問
.bashrc
,你會得到/home/tim/.bashrc
。如果你這樣做
chroot /filesystem/tim
了(假設有一個同名的目錄,並且你可以訪問它,並且你有必要的權限chroot
),那麼
- 如果你訪問
/etc/services
,你會得到/filesystem/tim/etc/services
,- 如果你訪問
/
,你會得到/filesystem/tim
,所以- 如果你
chroot /
,什麼都不會改變;- 如果你
chroot /filesystem/john
,它會盡力chroot
去/filesystem/tim/filesystem/john
。由於根目錄和目前目錄儲存為指向 inode 的指針,因此系統不需要“定位”它們。
1 即,查找指向模式指示它是目錄的inode 的目錄條目,即
(i_mode & IFMT) == IFDIR
。2 對於路徑名的最後一段,它不關心它是什麼類型的文件;它可以是一個目錄、一個普通文件、一個命名管道、一個符號連結、一個設備……等等。 3 如果沒有找到路徑名的最後一段,但係統呼叫是 or(等價的),或者任何其他不能創建目錄條目的東西,操作不會失敗。
creat(*file*, *mode*)``open(*file*, O_CREAT, *mode*)