Android 使用socketpair在两个进程之间通信时recvmsg返回错误(EBADF)?
我正在开发一个在两个进程之间执行IPC调用的程序。我使用socketpair创建两个套接字fd:Android 使用socketpair在两个进程之间通信时recvmsg返回错误(EBADF)?,android,linux,sockets,ipc,Android,Linux,Sockets,Ipc,我正在开发一个在两个进程之间执行IPC调用的程序。我使用socketpair创建两个套接字fd: int fds[2] = {-1,-1}; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { return NULL; } 在进程A(具有系统权限)中,我通过发送(使用fd[0])函数发送一个整数(句柄): int sock_send_all(int sock_fd, const uint8_t* buf, int len) {
int fds[2] = {-1,-1};
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
return NULL;
}
在进程A(具有系统权限)中,我通过发送(使用fd[0])函数发送一个整数(句柄):
int sock_send_all(int sock_fd, const uint8_t* buf, int len) {
int s = len;
int ret = send(sock_fd, buf, s, 0);
...
}
在进程B(具有用户权限)中,它等待通过recvmsg接收句柄(使用fd[1]):
这里出现问题:recvmsg立即返回-1,其中errorno等于9(EBADF)
我上网很久了,试图找到答案,但没有任何有用的信息。你有什么提示或建议吗?谢谢
这是关于进程特权级别的问题吗?或者我应该使用setsockopt来设置一些内容?除非我不知道IBinder的某些内容,否则一个进程中的句柄在另一个进程中无效。为什么你不能继续使用原来的插座?我已经解决了我的问题。
关键是将原始文件描述符封装到ParcelFileDescriptor对象中,并将该对象传输到另一个进程,而不是在两个进程之间直接传输文件描述符。
我认为在android中实现的ParcelFileDescriptor对原始文件描述符进行了一些配置。也许我应该阅读实现代码来找到真正的原因。
谢谢大家 进程B是如何获得fd[1]的?@EJP:我实际上是在Android平台上开发我的程序的。进程B是IBinder(Android IPC机制)的客户端进程。简单地说,fd[1]是通过另一个unix套接字接收的(我认为Android使用unix套接字在内核中实现IBinder驱动程序)。我确认在调用send和recvmsg之前,fd[0]和fd[1]的值与从socketpair返回的值相同。请显示用于发送和接收文件描述符的代码。此外,出于特权考虑,您可以在非特权情况下测试代码。你确定你所谓的“系统权限”应用程序真的有吗?仅仅在清单中声明它是不可能的。我正在Android中移植一些现有的代码,重写是一项漫长而乏味的工作:)这种交换没有多大意义。首先,像unix域sockets一样,Binder可以通过“魔法”传递可用的文件描述符,但在问题代码中没有证据表明这样做。回应中的评论毫无意义,因为它反对重新编写,而Binder只有在非Android代码被重写以使用Binder而不是unix套接字时才会成为一个因素…@ChrisStratton表示同意。整个事情对我来说没有意义。我有同样的问题,这也是我的解决方案。ParcelFileDescriptor必须作为其包在进程间传输,然后在到达另一个进程后重新序列化为ParcelFileDescriptor。传递原始int ParcelFileDescriptor.fd值是不够的。Unix/Android可能会为每个进程分配不同的int-fd值,这些值指向相同的底层管道。
ret = recvmsg(fd, &msg, MSG_NOSIGNAL);