0

I am new to C++ programming and I am trying to use mkfifo command to create a named pipe that I can read from my java program. Here is my code:

int main(int, char **)
{
    std::cout << "START" << std::endl;
    int fd;

    // FIFO file path
    char *myfifo = "/sdcard/tempFifo";

    // Creating the named file(FIFO)
    // mkfifo(<pathname>, <permission>)
    int ret = mkfifo(myfifo, 0666);
    std::cout << "mkfifo ret " << ret << std::endl;
    std::cout << "errno " << errno << std::endl;
    std::cout << "errno str::" << std::strerror(errno) << std::endl;

    char arr1[80];
    int startCount = 0;
    while (1)
    {

        // Open FIFO for Read only
        std::cout << "Opening FIFO.." << std::endl;
        fd = open(myfifo, O_RDONLY);

        // Read from FIFO
        std::cout << "Start reading.." << std::endl;
        read(fd, arr1, sizeof(arr1));

        if (strcmp(arr1, "start") == 0)
        {
            if (startCount == 1)
            {
                std::cout << "Start count is greater than one so exit." << std::endl;
                return 0;
            }
            startCount++;
            std::cout << "Start received" << std::endl;
        }

        sleep(5000);
        close(fd);
    }
    std::cout << "STOP" << std::endl;
    return 0;
}

To write "start" on the target pipe, I am using a java code as:

            File file = new File("/sdcard/tempFifo");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            PrintWriter printWriter = new PrintWriter(fileOutputStream);
            printWriter.print("start");
            printWriter.flush();
            printWriter.close();

I am getting Exception: /sdcard/tempFifo: open failed: ENOENT (No such file or directory) in java applicatoin and when I have executed ls -l /sdcard/tempFifo on adb shell then I am not able to see any tempFifo file on my sdcard of rooted phone.

Does anyone know what is the problem in my code?

Update on errno

mkfifo ret -1
errno 22
errno str::Invalid argument
Vatish Sharma
  • 1,536
  • 3
  • 16
  • 35
  • Just a guess: does a fifo need a non-FAT filesystem ? How did you format the SD card ? – Marged Jan 23 '20 at 06:57
  • 7
    What does `mkfifo` ***return?*** You must *always* check what functions that can fail returns. If `mkfifo` fails it will return `-1` and set `errno` to the reason it failed. Same with other calls you make (like e.g. `open` or `read`). – Some programmer dude Jan 23 '20 at 06:58
  • You can check `mkfifo`'s return value, see [man page](https://linux.die.net/man/3/mkfifo) – tjysdsg Jan 23 '20 at 07:03
  • mkfifo returns value is `-1` and the errno is `22` – Vatish Sharma Jan 23 '20 at 07:06
  • 2
    You must check both that `mkfifo()` returns zero and that `open()` does not return a negative value. If you don't check, you don't know whether they failed. File (FIFO) creation and file open operations are some of the calls most likely to fail — it is even more crucial that you check all such calls. Functions like `close()` can fail too; however, it isn't clear that you gain much benefit from checking whether that succeeded or not (interpreting what to do next is non-trivial). – Jonathan Leffler Jan 23 '20 at 07:06
  • `errno == 22` is probably `EINVAL` (invalid argument). `O_RDONLY` is normally zero; the second argument to `mkfifo()` is the permissions, and setting a FIFO so it cannot be read or written isn't helpful. You'd probably get errors like EPERM, ENOENT, EEXIST, etc if the problem was with the fifo name. – Jonathan Leffler Jan 23 '20 at 07:09
  • Use [strerror](https://en.cppreference.com/w/cpp/string/byte/strerror) to convert the error code in `errno` to a readable string after `mkfifo` fails. – Jesper Juhl Jan 23 '20 at 07:31
  • Its "Invalid argument" – Vatish Sharma Jan 23 '20 at 08:32
  • `mkfifo(myfifo, 0666);` and then `std::cout << "mkfifo ret " << ret << std::endl;` ? where do you declare and assign the `ret` ? – pptaszni Jan 23 '20 at 08:36

1 Answers1

1

Android doesn't allow creating pipes on /sdcard so, I have used /system/tempFifo instead of /sdcard/tempFifo to make it work.

Vatish Sharma
  • 1,536
  • 3
  • 16
  • 35
  • 1
    the proper location for temp files is /data/local/tmp (no root permissions required). for fifos you don't need much disk space, you can use /cache or even better don't use physical emmc at all (wear-out/performance) and create /dev/tmp – alecxs Feb 01 '20 at 13:47