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.

Reply via email to