android程序間傳遞檔案描述符原理

2021-08-01 03:34:48 字數 2099 閱讀 2957

在linux中,程序開啟乙個檔案,返回乙個整數的檔案描述符,然後就可以在這個檔案描述符上對該檔案進行操作。那麼檔案描述符和檔案到底是什麼關係?程序使用的是虛擬位址,不同程序間是位址隔離的,如何在兩個程序中傳遞檔案描述符,然後指向同一檔案(binder傳遞檔案描述符)?

下圖是linux核心中開啟檔案的結構體之間的關係圖(只是大概,細節可以參考各種核心書籍):

核心中每個程序都使用task_struct結構體表示,其成員files是乙個files_struct結構體,表示該程序開啟的所有檔案相關資訊; 

files_struct結構體中的fd_array陣列(上層應用程式返回的檔案描述符其實就是這個陣列的下標),是個struct file,核心對開啟的檔案都用file結構體描述,而成員fdt是個struct fdtable,其成員fd代表陣列fd_array的起始位址; 

struct file中的f_dentry表示檔案的dentry結構,而dentry中包含了檔案唯一的inode,即d_inode,d_inode唯一表示了該檔案(每個具體檔案只有乙個inode結構,而多個dentry可以指向同乙個inode,例如軟鏈結)。

下面簡要分析下**。 

上層:應用程式呼叫c庫中(實現依賴使用的c庫)的open()函式開啟乙個檔案,open()返回乙個檔案描述符; 

核心:上層open呼叫系統呼叫open函式,

syscall_define3(open, const

char __user *, filename, int, flags, int, mode)

實際呼叫的是

long do_sys_open(int dfd, const

char __user *filename, int flags, int mode)

else

}putname(tmp);

}return fd;

}

void fd_install(unsigned

int fd, struct file *file)

do_sys_open主要就完成了上面注釋的3步: 

獲取程序中未使用的fd,就是從0開始的整數,使用乙個往上+1; 

根據檔案的路徑,構建file結構體,即構建其中的dentry等; 

將fd、file結構體同本程序task_struct結構體建立關係。 

經過上面的分析,我們可以得到乙個結論: 

核心用struct file描述檔案,在單個程序中,開啟的檔案都儲存在程序結構體task_struct中files_struct結構體中的fd_array陣列中,而上層返回的檔案描述符就是這個陣列的下標,用來和struct file保持對應關係。因此在不同的程序中開啟同一檔案,核心都會建立乙個新的file結構用來和實際檔案關聯(但是同一檔案在不同程序中的file結構體主要內容是相同的,都描述了所指向的實際檔案),然後給上層返回不同的檔案描述符。

那麼如何將不同程序中的檔案描述符關聯為同一檔案?下面我們看看android binder通過傳遞檔案描述符如何實現同一檔案描述符的共享。

下面是核心binder_transaction函式中的一部分,

static

void binder_transaction(struct binder_proc *proc,

struct binder_thread *thread,

struct binder_transaction_data *tr, int reply)

break;

}

上述主要工作和前面open函式的實現類似,只不過是去獲取目標程序的未使用檔案描述符,然後將本程序的file結構體去和目標程序掛鉤(file結構體主要內容描述的都是具體檔案相關的,例如dentry,所以不同程序間可以共享,因為都是指向同一實際檔案),這樣binder驅動就悄無聲息的幫我們在核心中在目標程序中新建了檔案描述符,並將原程序的file結構與之掛鉤,就像在目標程序中開啟了原程序中的該檔案一樣,只不過返回給目標程序上層的描述符是新的target_fd。

android程序間傳遞檔案描述符原理

在linux中,程序開啟乙個檔案,返回乙個整數的檔案描述符,然後就可以在這個檔案描述符上對該檔案進行操作。那麼檔案描述符和檔案到底是什麼關係?程序使用的是虛擬位址,不同程序間是位址隔離的,如何在兩個程序中傳遞檔案描述符,然後指向同一檔案 binder傳遞檔案描述符 核心中每個程序都使用task st...

程序間傳遞訊息

使用自定義訊息 1 首先定義訊息 例如 define wm yourmesg wm user 100 2 加入訊息響應巨集,在響應該訊息的類中 c c code?1 2 3 4 5 begin message map cchiliddlg,cdialog afx msg map end messag...

Linux 程序間傳遞檔案描述符

程序間傳遞開啟的檔案描述符,並不是傳遞檔案描述符的值。先說一下檔案描述符。對核心來說,所有開啟的檔案都會通過檔案描述符引用,檔案描述符在程序中是乙個非負整數,檔案描述符在程序中是從0開始,預設0與標準輸入關聯 1與標準輸出關聯 2與標準出錯關聯。之後程序每開啟乙個檔案或者建立乙個新檔案的時候,核心都...