部落格:blog.focus-linux.net linuxfocus.blog.chinaunix.net
本文的copyleft歸[email protected]所有,使用GPL釋出,可以自由拷貝,轉載。但轉載請保持文檔的完整性,注明原作者及原連結,嚴禁用于任何商業用途。
======================================================================================================
在sock_alloc_file成功傳回後,回到函數sock_map_fd中
int sock_map_fd(struct socket *sock, int flags)
{
struct file *newfile;
int fd = sock_alloc_file(sock, &newfile, flags);
if (likely(fd >= 0))
fd_install(fd, newfile);
return fd;
}
這時,sock->file = new_file, 而newfile->private_data = sock,也就是sock已經和file互相關聯起來,file的各種檔案操作也指向socket的各種操作。但是與fd還沒有建立起聯系。當sock_alloc_file成功傳回時,fd自然大于等于0,進入函數fd_install,這個函數将把檔案描述符fd與檔案結構file關聯。自然通過file,fd與socket也就關聯起來。
//這個函數很簡單
void fd_install(unsigned int fd, struct file *file)
/* 得到目前程序的檔案表 */
struct files_struct *files = current->files;
struct fdtable *fdt;
spin_lock(&files->file_lock);
/* 獲得檔案描述符表 */
fdt = files_fdtable(files);
BUG_ON(fdt->fd[fd] != NULL);
/* 将建立立的file結構賦給對應的檔案描述符為索引的指針 */
rcu_assign_pointer(fdt->fd[fd], file);
spin_unlock(&files->file_lock);
ok。這時已經完成了,socket,fd,和file三者的關聯。
簡單描述一下三者之間的關聯。
每個程序維護了一個打開的檔案表,可使用current->files得到,該結構如下:
/*
* Open file table structure
*/
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
struct fdtable *fdt; //檔案描述符表
struct fdtable fdtab;//這個我不知道用途是做什麼
* written part on a separate cache line in SMP
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd;
struct embedded_fd_set close_on_exec_init;
struct embedded_fd_set open_fds_init;
//實作申請的預設個數的file指針
struct file * fd_array[NR_OPEN_DEFAULT];
};
通過檔案描述符,可以得到内部的檔案結構體current->files->fdt->fd[socket_fd]——其中socket_fd為傳入的檔案描述符。由于在建立socket的時候,已經将檔案的各種操作函數,綁定到socket的各種操作函數。這樣,當使用socket傳回的檔案描述符,進行各種檔案操作,實際上就是對socket執行各種socket指定的操作。