have a look at this code:
#include<stdio.h>
#include <unistd.h>
int main()
{
int pipefd[2],n;
char buf[100];
if(pipe(pipefd)<0)
printf("Pipe error");
printf("\nRead fd:%d write fd:%d\n",pipefd[0],pipefd[1]);
if(write(pipefd[1],"Hello Dude!\n",12)!=12)
printf("Write error");
if((n=read(pipefd[0],buf,sizeof(buf)))<=0)
printf("Read error");
write(1,buf,n);
return 0;
}
I expect the printf to print Read fd and write fd before Hello Dude is read from the pipe. But thats not the case… see here. When i tried the same program in our college computer lab my output was
Read fd:3 write fd:4
Hello Dude!
also few of our friends observed that, changing the printf statement to contain more number of \n characters changed the output order… for example..printf("\nRead fd:%d\n write fd:%d\n",pipefd[0],pipefd[1]); meant that Read fd is printed then the message Hello Dude! then the write fd is printed. What is this behaviour??
Note: Out lab uses a linux server on which we run terminals, i don’t remember the compiler version though.
It’s because
printfto the standard output stream is buffered butwriteto the standard output file descriptor is not.That means the behaviour can change based on what sort of buffering you have. In C, standard output is line buffered if it can be determined to be connected to an interactive device. Otherwise it’s fully buffered (see here for a treatise on why this is so).
Line buffered means it will flush to the file descriptor when it sees a newline. Fully buffered means it will only flush when the buffer fills (for example, 4K worth of data), or when the stream is closed (or when you
fflush).When you run it interactively, the flush happens before the
writebecauseprintfencounters the\nand flushes automatically.However, when you run it otherwise (such as by redirecting output to a file or in an online compiler/executor where it would probably do the very same thing to capture data for presentation), the flush happens after the
write(becauseprintfis not flushing after every line).In fact, you don’t need all that pipe stuff in there to see this in action, as per the following program:
When I execute
myprog ; echo === ; myprog >myprog.out ; cat myprog.out, I get:and you can see the difference that the different types of buffering makes.
If you want line buffering regardless of redirection, you can try:
early on in your program – it’s implementation defined whether an implementation supports this so it may have no effect but I’ve not seen many where it doesn’t work.