Passing file descriptor
来源:互联网 发布:tensorflow wordvec 编辑:程序博客网 时间:2024/05/29 15:38
在<<The Linux Programming Interface>>书中的61.13.2小节,有这样的描述:
The sendmsg() system call can do everything that is done by write(), send(), andsendto(); the recvmsg() system call can do everything that is done by read(),recv(), and recvfrom(). In addition, it also can perform scatter-gather I/O and transmit ancillary data (also known as control information).
这里说的意思是sendmsg/recvmsg除了能够进行正常的数据发送之外,还能够用来传递ancillary data数据。这里所说的ancillary data包括两类信息:file descriptor和sender credential。这里我们关注file descriptor,因为credential与之类似。
为了传递file descriptor,需要使用UNIX domain socket(可以为TDP,也可以是UDP)。使用UNIX domain socket就限定file descriptor仅仅在同一个host上有效,从机器A传递进程Pa的fd到机器B的进程Pb,显然不能使用。Why?UNIX-like机器上的文件索引结构如下:
既然fd是file descriptor table中的index,它指向当前系统上kernel中的open file description,为此从机器A传递到机器B,机器B上的open file description与A不同,为此跨机器传递fd无效。
通过查看linux-2.6.0的代码,发现其原理是:
o Sender通过UNIX domain socket把passing file descriptor通过SCM_RIGHTS消息发送给receiver。
o 当该消息传递给kernel时,kernel会调用__send_fd_copy(cmsg,scm_cookie->fp)来把filedescriptor对应的openfile description的文件地址记录到scm_cookie->fp。
o Receiver通过UNIX domain socket来接收消息时,会调用unix_dgram_recvmsg/unix_stream_recvmsg:
§ 它们会判断是否scm_cookie->fp为NULL。如果不为NULL,则表示正在传递file descriptor,此时会调用scm_fp_dup(scm_cookie->fp)来把存放在scm_cookie->fp中的文件地址复制到siocb->scm->fp。这里siocb是上面函数的局部变量,类型为structsock_iocb*。
§ 然后调用scm_recv(sock, msg, siocb->scm,flags) => scm_detach_fds(msg, siocb->scm)。
§ 在scm_detach_fds中,它会根据传递的file descriptor的个数,从index从0开始,分配未使用的fd,然后把该fd写入cmsg中对应该index的fd位置(这个才是在receiver中能够使用的fd)[因为要写入到userspace,所以这里使用的是put_user函数:put_user(new_fd,cmfptr)],然后把它关联到前面记录在siocb->scm->fp中的文件地址。至此,sender在cmsg中传递的filedescriptor已经被替代为receiver中有效的fd,它指向同sender中fd一样的openfile description对象。
o 上面的步骤发生在kernel,为此当receiver从调用函数recvmsg中返回时,从cmsg中得到的fd将是有效的fd,且指向与sender对应fd相同的文件(open file description)。
- Passing file descriptor
- Mechanism of Android while Passing File Descriptor through Binder
- File descriptor(FD)
- bad file descriptor
- 获得目录的file descriptor.
- 文件描述符 (file descriptor)
- select with reglar file descriptor
- send file descriptor via socket
- select error:bad file descriptor
- socket编程时 send: Bad file descriptor
- mysql 中的异常 Bad file descriptor
- 关于文件描述符(File descriptor)
- sys.setdefaultencoding 引发 [Bad file descriptor]解决
- TypeError:First argument must be file descriptor
- Linux 文件描述符简介(file descriptor)
- Http bad file descriptor
- Linux之file_struct&fd(file descriptor)
- Linux socket连接数(file descriptor)
- Java中静态代码块的用法
- 后台读取properties配置文件
- 最大子序列和问题 hdu1231
- JavaScript的Ajax以及中文乱码问题
- objc[8715]: Class JavaLaunchHelper is implemented in both...
- Passing file descriptor
- python基础--文件操作实现全文或单行替换
- [题解]hdu1542 Atlantis
- 前端拖拽插件gridster.js介绍与使用示例
- java实现时间复杂度O(1)的LFU缓存
- 内置的验证约束注解
- C++ 判断文件文件夹是否存在
- 最近点对模版
- Hibernate错误记录(一): Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPe