On Mon, Oct 23, 2023 at 11:15:22AM +0200, Thomas Schmitt wrote: > it helps to do > fflush((stdout); > after each printf(), or to run before the loop: > setvbuf(stdout, NULL, _IONBF, 0); > > So it is obvious that the usual output buffering of printf() causes the > repetitions of text.
Yes, it looks like a buffering issue to me as well. Or, more generally, some kind of weird interaction between buffered stdio FILEs and the underlying Unix file descriptors, when new processes are being fork()ed. > The loop does not do any extra cycles, as i could confirm by inserting Here's another interesting observation: using the original program with only the argc/argv change, there is different behavior depending on whether stdin points to a file, or a pipe. unicorn:~$ seq 1 2 | ./foo 1 num_read: 2 at line 1 2 num_read: 2 at line 2 unicorn:~$ seq 1 2 > bar unicorn:~$ ./foo < bar 1 num_read: 2 at line 1 2 num_read: 2 at line 2 2 num_read: 2 at line 3 unicorn:~$ Clearly there are different mechanisms in play based on whether stdin is a regular file or a pipe. I can't fully explain this result, though. On Mon, Oct 23, 2023 at 12:59:38AM -0400, tom kronmiller wrote: > Without the fork/exit/waitpid block of code, it prints the input > successfully. With that code included, it goes into an infinite loop > printing the first 78 lines of input, Every second pass over the input,the > 78th line is garbled. > 77 77 77 77 77xx > 78 1 1xx The 78th line looks like it's truncated after 16 characters. > num_read: 30 at line 6433 > 2 2 2 2 2xx > > The input file "lines" is (all lines 52 charactures + \n == 53 characters): 53 * 77 = 4081 Add the 16 characters of the truncated line and you're right around the magic number 4096, which is very likely the buffer size. So, even if I can't explain every detail, this is another strong clue that stdio buffering is involved somehow.