Augustine Calmet
Augustine Calmet

Reputation: 11

Pipe in MacOS always reads too few bytes (but Linux works)

This code works beautifully in Linux, but with MacOS it always fails to read the tree (it will read too bytes). It works with redirection from a file. It reads when a file is explicitly opened. But on a pipe, always too few bytes.

// Load the saved tree

    uint16_t treeBytes = 0;

    read(fileIn, &treeBytes, sizeof(treeBytes));

    if (verbose) { printf("tree (%u)\n", treeBytes); }

    uint8_t  savedTree[treeBytes];

    int readSz = read(fileIn, savedTree, treeBytes);
    if (readSz != treeBytes)
    {
            fprintf(stderr, "%d != %u: ", readSz, treeBytes);
            ERROR("Truncated tree read");
    }

Upvotes: 0

Views: 54

Answers (1)

Warren Young
Warren Young

Reputation: 42343

There are two bugs here:

  1. You aren't checking the return from the first read() call. There are four possible returns here, three of which will break your program: -1 on error, 0 on abnormal close (typical for sockets only), 1 for a short read, and 2 (sizeof(treeBytes)) for a successful read. Don't assume.

  2. You are collapsing those three failure cases as one in your second read(), which probably explains your reported symptom. There is nothing mandating that read() must block until it gets treeBytes from the pipe. It is allowed to return 1 byte at a time for a blocking FD, and 0 for a nonblocking FD. As Mark Sechell comented above, read in a loop until you have as many bytes as you expect or you hit an error case.

Upvotes: 3

Related Questions