2012-06-14 16:13:45

by Dave Jones

[permalink] [raw]
Subject: 3.5.rc2 tty buffering bug ?

I found something odd that happens with redirection.

this code...



#include <stdio.h>

void main()
{
printf("begin\n");

if (fork() != 0)
printf("child\n");
else
printf("parent\n");

printf("end\n");
}

usually exits before the child gets to print anything, so stdout looks like..

begin
parent
end

but when redirected to a file, sometimes it prints what we expect, but other times
(if the child exits first) it seems to print..

begin
child
end
begin
parent
end


How does 'begin' get printed a second time ?

Dave


2012-06-14 16:23:09

by Dave Jones

[permalink] [raw]
Subject: Re: 3.5.rc2 tty buffering bug ?

On Thu, Jun 14, 2012 at 12:13:31PM -0400, Dave Jones wrote:

> #include <stdio.h>
>
> void main()
> {
> printf("begin\n");
>
> if (fork() != 0)
> printf("child\n");
> else
> printf("parent\n");
>
> printf("end\n");
> }
>
> How does 'begin' get printed a second time ?

Someone pointed out that an fflush is needed before the fork.
Somehow I've managed to go all these years without knowing that.

Dave

2012-06-14 16:30:37

by Andreas Schwab

[permalink] [raw]
Subject: Re: 3.5.rc2 tty buffering bug ?

Dave Jones <[email protected]> writes:

> How does 'begin' get printed a second time ?

It's buffered in stdio, which is then cloned.

Andreas.

--
Andreas Schwab, [email protected]
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

2012-06-14 16:38:14

by Alan

[permalink] [raw]
Subject: Re: 3.5.rc2 tty buffering bug ?

> How does 'begin' get printed a second time ?

You've been away from user space too long. Read the documentation for
stdio. Stdio is buffering, both forks get the buffer, both write it.

Try the experiment with write()

Alan

2012-06-15 10:32:57

by Cong Wang

[permalink] [raw]
Subject: Re: 3.5.rc2 tty buffering bug ?

On Fri, Jun 15, 2012 at 12:13 AM, Dave Jones <[email protected]> wrote:
> but when redirected to a file, sometimes it prints what we expect, but other times
> (if the child exits first) it seems to print..
>
> begin
> child
> end
> begin
> parent
> end
>
>
> How does 'begin' get printed a second time ?
>

setbuf(3) said:

"
Normally all files are block buffered. [...]
If a stream refers to a terminal (as stdout normally does) it is line buffered.
The standard error stream stderr is always unbuffered by default.
"
So when you redirect stdout to a file, "begin\n" is buffered too, both
in child and in parent.