如何在 Android 中创建命名管道 (mkfifo)?

编程入门 行业动态 更新时间:2024-10-24 16:31:56
本文介绍了如何在 Android 中创建命名管道 (mkfifo)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我在 Android 中创建命名管道时遇到了麻烦,下面的示例说明了我的困境:

I am having trouble in creating named pipe in Android and the example below illustrates my dilemma:

res = mkfifo("/sdcard/fifo9000", S_IRWXO); if (res != 0) { LOG("Error while creating a pipe (return:%d, errno:%d)", res, errno); }

代码总是打印出来:

Error while creating a pipe (return:-1, errno:1)

我无法弄清楚这失败的确切原因.该应用程序具有 android.permission.WRITE_EXTERNAL_STORAGE 权限.我可以在同一位置创建具有完全相同名称的普通文件,但管道创建失败.有问题的管道应该可以从多个应用程序访问.

I can't figure out exactly why this fails. The application has android.permission.WRITE_EXTERNAL_STORAGE permissions. I can create normal files with exactly the same name in the same location, but pipe creation fails. The pipe in question should be accessible from multiple applications.

  • 我怀疑没有人可以在/sdcard 中创建管道.这样做的最佳地点在哪里?
  • 我应该设置什么模式桅杆(第二个参数)?
  • 应用程序是否需要任何额外权限?
  • 推荐答案

    Roosmaa 的回答 是正确的 -- mkfifo()只是调用 mknod() 来创建一个特殊的文件,而 FAT32 不支持.

    Roosmaa's answer is correct -- mkfifo() just calls mknod() to create a special file, and FAT32 doesn't support that.

    作为替代方案,您可能需要考虑使用 Linux 的抽象名称空间"UNIX 域套接字.它们应该大致相当于命名管道.您可以按名称访问它们,但它们不是文件系统的一部分,因此您不必处理各种权限问题.注意套接字是双向的.

    As an alternative you may want to consider using Linux's "abstract namespace" UNIX-domain sockets. They should be roughly equivalent to a named pipe. You can access them by name, but they're not part of the filesystem, so you don't have to deal with various permission issues. Note the socket is bi-directional.

    由于它是一个套接字,您可能需要 INTERNET 权限.不确定.

    Since it's a socket, you may need INTERNET permission. Not sure about that.

    这里有一些客户端/服务器示例代码:

    Here's a quick bit of client/server sample code:

    #include <stdio.h> #include <string.h> #include <unistd.h> #include <stddef.h> #include <sys/socket.h> #include <sys/un.h> /* * Create a UNIX-domain socket address in the Linux "abstract namespace". * * The socket code doesn't require null termination on the filename, but * we do it anyway so string functions work. */ int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen) { int nameLen = strlen(name); if (nameLen >= (int) sizeof(pAddr->sun_path) -1) /* too long? */ return -1; pAddr->sun_path[0] = ''; /* abstract namespace */ strcpy(pAddr->sun_path+1, name); pAddr->sun_family = AF_LOCAL; *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path); return 0; } int main(int argc, char** argv) { static const char* message = "hello, world!"; struct sockaddr_un sockAddr; socklen_t sockLen; int result = 1; if (argc != 2 || (argv[1][0] != 'c' && argv[1][0] != 's')) { printf("Usage: {c|s} "); return 2; } if (makeAddr("com.whoever.xfer", &sockAddr, &sockLen) < 0) return 1; int fd = socket(AF_LOCAL, SOCK_STREAM, PF_UNIX); if (fd < 0) { perror("client socket()"); return 1; } if (argv[1][0] == 'c') { printf("CLIENT %s ", sockAddr.sun_path+1); if (connect(fd, (const struct sockaddr*) &sockAddr, sockLen) < 0) { perror("client connect()"); goto bail; } if (write(fd, message, strlen(message)+1) < 0) { perror("client write()"); goto bail; } } else if (argv[1][0] == 's') { printf("SERVER %s ", sockAddr.sun_path+1); if (bind(fd, (const struct sockaddr*) &sockAddr, sockLen) < 0) { perror("server bind()"); goto bail; } if (listen(fd, 5) < 0) { perror("server listen()"); goto bail; } int clientSock = accept(fd, NULL, NULL); if (clientSock < 0) { perror("server accept"); goto bail; } char buf[64]; int count = read(clientSock, buf, sizeof(buf)); close(clientSock); if (count < 0) { perror("server read"); goto bail; } printf("GOT: '%s' ", buf); } result = 0; bail: close(fd); return result; }

    更多推荐

    如何在 Android 中创建命名管道 (mkfifo)?

    本文发布于:2023-11-05 04:53:05,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1559954.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:管道   如何在   Android   mkfifo

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!