How to create named pipe (mkfifo) in Android?

后端 未结 5 1861
南方客
南方客 2020-12-13 07:35

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         


        
5条回答
  •  忘掉有多难
    2020-12-13 08:20

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

    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.

    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 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    /*
     * 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] = '\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}\n");
            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\n", 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\n", 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'\n", buf);
        }
        result = 0;
    
    bail:
        close(fd);
        return result;
    }
    

提交回复
热议问题