binder传递fd的机制

进程获得的fd是进程fd table中的index, 在fd table中记录了file指针, file对象保留在kernel空间中.

因此不同进程间传递fd本身并没有什么意义.


binder通过parcel传递fd的本质, 是将源进程的fd table中对应项指针, 记录到target进程的fd table中.

client端add的fd和server端读出的是两个值. 但实际上指向的是一个file对象.

这有些类似于dup(), 不过dup是在同一进程中复制两个fd, 指向一个file对象. 而binder传递后是在两个进程中.


android进程在fork之后, 会构造processState, 在其构造函数中首先open binder, 之后执行mmap.

这个mmap调用在binder driver这一层会将源进程的current->files保存到对应binder_proc的files中.

 proc->files = get_files_struct(current);


到了真正transact的时候, binder driver会判断flat_binder_object类型, 如果是BINDER_TYPE_FD,

就通过fget(fd)获得源binder_proc中files记录的file对象, 并通过task_fd_install保存到目标进程的fd table中.

1633         case BINDER_TYPE_FD: {
1634             int target_fd;
1635             struct file *file;
1636
1651             file = fget(fp->handle);
1652             if (file == NULL) {
1653                 binder_user_error("%d:%d got transaction with invalid fd, %d\n",
1654                     proc->pid, thread->pid, fp->handle);
1655                 return_error = BR_FAILED_REPLY;
1656                 goto err_fget_failed;
1657             }
1663             target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
1664             if (target_fd < 0) {
1665                 fput(file);
1666                 return_error = BR_FAILED_REPLY;
1667                 goto err_get_unused_fd_failed;
1668             }
1669             task_fd_install(target_proc, target_fd, file);
1674             fp->handle = target_fd;
1675         } break;

也就是说, binder driver替binder通信的另一端在底层打开了这个文件. 只不过, 这个打开不是通常的open方式,

而是在驱动层将已有的file指针复制了过去.  因此, 同dup类似, 两个进程的fd享有相同的file offset和file status flag.

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值