如何在进程之间将文件描述符传递给Ashmem

卡祖杜尔

我正在尝试将指向ashmem区域的文件描述符从Service(进程A)传递到Activity(进程B)。在Service中,我将本机文件描述符放入ParcelFileDescriptor并将其放入捆绑包中,然后通过Messenger发送。但是,当我尝试在Activity中使用此文件描述符进行mmap()时,得到errno == 9(EBADF,错误的文件号)。

在Service的JNI中创建ashmem区域:

int fd;
int *buff;
JNIEXPORT jint JNICALL Java_com_example_testservice_Test_getTestFD
/* int Test.getTestFD() */
 (JNIEnv * env, jclass jthis) {
    fd = open("/dev/ashmem", O_RDWR); // I couldn't find library with ashmem_create_region
    ioctl(fd, ASHMEM_SET_NAME, "my_mem");
    ioctl(fd, ASHMEM_SET_SIZE, 640*480*12);
    buff = mmap(NULL, 640*480*12, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(buff == MAP_FAILED)
        return -1;
    buff[0] = 4;
    buff[1] = 5;
    buff[2] = 6;
    return fd;
  }

将fd从服务发送到活动:

int nFD = Test.getTestFD();
ParcelFileDescriptor fd;
try {
    fd = ParcelFileDescriptor.fromFd(nFD);
    Message reply = Message.obtain(this, msg.what, nFD, 0);
    Bundle b = new Bundle(1);
    b.putParcelable("fd", fd);
    reply.setData(b);
    if(msg.replyTo == null) { // Activity asks for FD and we reply to it's message
        Log.e("TestService", "Missing replyTo");
    } else {
        try {
            msg.replyTo.send(reply);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
} catch (IOException e1) {
    e1.printStackTrace();
}

在活动中接收fd:

Bundle bundle = msg.getData();
ParcelFileDescriptor fd = bundle.getParcelable("fd");
int nFD = fd.getFd();
Log.d("ClientLib", "Received FD (Parcel): "+String.valueOf(nFD));
Log.d("ClientLib", "Received FD (raw): "+String.valueOf(msg.arg1));
int ret = Interface.SetDataFD(nFD);  // implementation below
if(ret != 0)
    Log.e("ClientLib", "SetDataFD (parcel) failed. Error code: "+String.valueOf(ret));

ret = Interface.SetDataFD(msg.arg1);
if(ret != 0)
    Log.e("ClientLib", "SetDataFD (raw) failed. Error code: "+String.valueOf(ret));

在Activity的JNI中处理fd:

int data_fd = -1;
JNIEXPORT
jint JNICALL Java_com_example_clientlib_Interface_SetDataFD
/* int SetDataFD(int fd) */
(JNIEnv * env, jclass jthis, jint fd)
{
    data_fd = fd;
    int * blah = (int*)mmap(NULL, 16, PROT_READ, MAP_SHARED, data_fd, 0);
    if(blah == MAP_FAILED)
        return errno;
    return 0;
}

这是我在logcat中得到的:

D/ClientLib(22104): Received FD (Parcel): 53
D/ClientLib(22104): Received FD (raw): 49
E/ClientLib(22104): SetDataFD (parcel) failed. Error code: 9
E/ClientLib(22104): SetDataFD (raw) failed. Error code: 19

怎么了 我什至不确定传递文件描述符是否有问题,我不知道还能检查什么。

卡祖杜尔

没关系,它可以正常工作:)。我在代码中某处有一些愚蠢的调试+9,它正确地返回0。我将代码留作参考。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

“在进程之间传递文件描述符”如何工作?

来自分类Dev

在线程之间转发/传递文件描述符

来自分类Dev

在线程之间转发/传递文件描述符

来自分类Dev

将文件描述符传递给使用spawn_link创建的进程

来自分类Dev

使用共享内存在两个进程之间传递套接字描述符

来自分类Dev

使用共享内存在两个进程之间传递套接字描述符

来自分类Dev

套接字文件描述符在不同进程之间是相同的

来自分类Dev

为什么在分叉的进程之间共享文件描述符?

来自分类Dev

套接字文件描述符可以传递给子进程吗?

来自分类Dev

如何将描述符作为整数传递给函数?

来自分类Dev

将进程替换的文件描述符放入变量

来自分类Dev

execvp后如何在子进程中使用文件描述符?

来自分类Dev

如何在多个子进程中使用文件描述符的文件指针,而又不会在C中出现“错误的文件描述符”错误?

来自分类Dev

如果知道进程打开的文件的文件描述符,如何在linux命令上打印文件名?

来自分类Dev

如何在Bash中写入命名文件描述符?

来自分类Dev

如何在python中关闭文件描述符?

来自分类Dev

如何在C中返回文件描述符

来自分类Dev

如何在共享标准输出文件描述符的进程的 systemd 日志中拥有 PID?

来自分类Dev

如何使文件描述符的别名可读

来自分类Dev

如何模拟缺少文件描述符?

来自分类Dev

如何获得文件描述符的模式?

来自分类Dev

如何保留文件描述符?

来自分类Dev

文件描述符和套接字文件描述符之间的区别

来自分类Dev

如何找到具有最大文件描述符的进程?

来自分类Dev

子进程退出时,父级应如何关闭管道文件描述符

来自分类Dev

如何检查哪个进程正在使用给定的文件描述符?

来自分类Dev

嵌套的进程替换后跟管道:“错误的文件描述符”

来自分类Dev

计算由lsof进程打开的文件描述符的数量

来自分类Dev

使用python显示进程的文件描述符

Related 相关文章

  1. 1

    “在进程之间传递文件描述符”如何工作?

  2. 2

    在线程之间转发/传递文件描述符

  3. 3

    在线程之间转发/传递文件描述符

  4. 4

    将文件描述符传递给使用spawn_link创建的进程

  5. 5

    使用共享内存在两个进程之间传递套接字描述符

  6. 6

    使用共享内存在两个进程之间传递套接字描述符

  7. 7

    套接字文件描述符在不同进程之间是相同的

  8. 8

    为什么在分叉的进程之间共享文件描述符?

  9. 9

    套接字文件描述符可以传递给子进程吗?

  10. 10

    如何将描述符作为整数传递给函数?

  11. 11

    将进程替换的文件描述符放入变量

  12. 12

    execvp后如何在子进程中使用文件描述符?

  13. 13

    如何在多个子进程中使用文件描述符的文件指针,而又不会在C中出现“错误的文件描述符”错误?

  14. 14

    如果知道进程打开的文件的文件描述符,如何在linux命令上打印文件名?

  15. 15

    如何在Bash中写入命名文件描述符?

  16. 16

    如何在python中关闭文件描述符?

  17. 17

    如何在C中返回文件描述符

  18. 18

    如何在共享标准输出文件描述符的进程的 systemd 日志中拥有 PID?

  19. 19

    如何使文件描述符的别名可读

  20. 20

    如何模拟缺少文件描述符?

  21. 21

    如何获得文件描述符的模式?

  22. 22

    如何保留文件描述符?

  23. 23

    文件描述符和套接字文件描述符之间的区别

  24. 24

    如何找到具有最大文件描述符的进程?

  25. 25

    子进程退出时,父级应如何关闭管道文件描述符

  26. 26

    如何检查哪个进程正在使用给定的文件描述符?

  27. 27

    嵌套的进程替换后跟管道:“错误的文件描述符”

  28. 28

    计算由lsof进程打开的文件描述符的数量

  29. 29

    使用python显示进程的文件描述符

热门标签

归档