The scheduler. You are in a loop that asks the child (i.e. the pgm file
) to look up two files three times. You only do one read per loop in the parent.
- If the child is scheduled and uninterrupted it performs the first file lookup, writes the pipe, does the second lookup, writes to the pipe. Parent gets scheduled and you read the full output of the child in one read. You are golden (but lucky).
- The child is scheduled, does the first lookup and pipe write and gets interrupted. The parent reads one output. The child gets rescheduled and does the 2nd lookup and writes the pipe. The parent reads one output. Because you only read 3 times you end up only reading 3 of the 6 outputs.
- Variations on the above. Maybe you'll read 1 output then 3 then 1. You just don't know.
Note that the reason you are at least getting a full child output on each read is because pipe writes are guaranteed to be atomic if they under PIPE_BUF length, which these are. If you were using this kind of a routine on, say a socket, you may end up getting some fractional portion of a message on each read.
Solution: You have to read in a loop until you have the number of bytes (or full message) that you expect. In this case I assume the output of file
is always one string ending in a newline. But you are asking for two file
outputs each time through the loop. So read until that condition is met, namely until you read two full strings.