2015-09-04 76 views
0

下面的代碼是從Debian的手動open(2)頁面從描述O_TMPFILE標誌該段採取:爲什麼linkat需要路徑名而不是文件描述符?

char path[PATH_MAX]; 
fd = open("/path/to/dir", O_TMPFILE | O_RDWR, 
      S_IRUSR | S_IWUSR); 

/* File I/O on 'fd'... */ 

snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd); 
linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file", 
     AT_SYMLINK_FOLLOW); 

的代碼背後的想法是,你創建一個匿名的文件,該文件還沒有名字的文件系統,但只是一個文件描述符。這意味着沒有人知道該文件並可以訪問它。然後你寫這個文件。最後,文件通過linkat得到它的名字。之後,文件可見,其他人都可以訪問它。這是處理下載文件的完美方式,以確保只有完整的下載文件可以被其他程序使用。

但方式linkat必須被稱爲看起來破碎的設計給我。 linkat有效嗎?它給文件描述符一個名字。這意味着該函數需要兩個參數:文件描述符和名稱。相反,它不接受文件描述符作爲參數,但需要文件的名稱,該名稱沒有名稱。這使得有必要依靠已安裝的proc文件系統爲未命名的文件創建一個名稱,以便能夠將該名稱傳遞給linkat。這看起來如此有線,我不知道爲什麼有人發明了這個。

爲什麼以這種方式實現,爲什麼會出現不只是一個函數

link_what_ever (int fd, char *name); 
+0

正如你寫的O_TMPFILE創建一個匿名文件,沒有人知道該文件,並且可以訪問它。這就是它的作用,如果存儲在該文件中的信息必須保存,則可以簡單地創建新文件並將隱藏文件複製到其中。 Linkat與O_TMPFILE沒有關聯,它創建一個新的鏈接(也稱爲硬鏈接)到一個現有的文件。 – LPs

+0

請勿編輯我的回答以發表評論。 – Barmar

+0

如果我的答案不起作用,你在運行什麼內核版本?在Linux 2.6.39中增加了「AT_EMPTY_PATH」。 – Barmar

回答

1

我認爲你可以做你想做與AT_EMPTY_PATH標誌是什麼。

linkat(fd, "", AT_FDCWD, "/path/for/file", AT_EMPTY_PATH); 

當使用此標誌時,它會創建一個指向由olddirfd參數標識的文件的鏈接。

請注意,使用此標誌要求調用方擁有CAP_DAC_READ_SEARCH的能力。

0

linkat做什麼有效?它給文件描述符一個名字。

不,你的假設是錯誤的:linkat(2),就像link(2),是爲了給一個名字命名的文件(即創建一個硬鏈接),這是一個有點不同。它的設計目的並不在於爲匿名文件命名。相反,它是一個通用接口,允許您爲已存在的文件Y創建一個新名稱X

你可能會說有人可以實現另一個功能name_anon_file(int fd, char *name),的確如此,但在linkat(2)之上實現它並不難,所以你可以自己動手。

另外,不是每個UNIX變體都支持O_TMPFILE,所以這個函數在一般情況下不會很有用。

+0

如何在不安裝proc文件系統的情況下實現'name_anon_file'? – ceving

+0

@ceving它不能。無論哪種方式,如果'/ proc'沒有掛載,那麼你的狀態就很糟糕了,像'ps(1)'和'lsof(1)'這樣的東西是行不通的。 –

相關問題