binder传递fd的机制

本文详细解析了Android系统中Binder机制如何实现不同进程间的文件描述符(FD)传递,介绍了Binder驱动如何在底层复制file对象指针,以及该过程与dup操作的相似之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程获得的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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值