Reputation: 11
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
Reputation: 42343
There are two bugs here:
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.
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