On 03/19/2013 06:59 AM, 竹下幸夫 wrote:
> Hi there, I tried to read the binder driver but it's impossible for me to
> understand, and actually understanding it at this level only helps me
> adding one or two lines to my presentation so it's not worth sticking my
> nose too much into the low level code. I only have a quick question here:
> how does a binder pass FD from this process to another? How could it make
> the receiver be able to handle the file? Does it change the receiver's file
> descriptor table?
> Thank you so much.
>
Hi 竹下幸夫,
see userspace code here:
status_t Parcel::writeFileDescriptor(int fd)
{
flat_binder_object obj;
obj.type = BINDER_TYPE_FD;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
obj.handle = fd;
obj.cookie = (void*)0;
return writeObject(obj, true);
}
and the driver code below:
------------------
case BINDER_TYPE_FD: {
int target_fd;
struct file *file;
if (reply) {
if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}
} else if (!target_node->accept_fds) {
binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}
file = fget(fp->handle);
if (file == NULL) {
binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fget_failed;
}
target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
if (target_fd < 0) {
fput(file);
return_error = BR_FAILED_REPLY;
goto err_get_unused_fd_failed;
}
task_fd_install(target_proc, target_fd, file);
binder_debug(BINDER_DEBUG_TRANSACTION,
" fd %ld -> %d\n", fp->handle, target_fd);
/* TODO: fput? */
fp->handle = target_fd;
} break;
-------------
as you can see, the binder driver open the same file in the target process..
--
Kaspter Ju