view raw
Alexey Alexey - 8 months ago 37
Linux Question

Why linux pipes and stdout from exec not working together?

Im writing code with linux pipes and dont understand, why only printfs (1) or only exec (2) goes to input of parent process. If I comment exec, than printf work fine. If uncomment, only "ls" output shown

int main(void)
int fd[2], pid;
if (pipe(fd) != 0) return 1;
if ((pid = fork()) == -1) return 1;
if (pid == 0) // child
dup2( fd[1], STDOUT_FILENO );

close( fd[0] );
close( fd[1] ); // */

printf( "hello\n" ); // (1)
printf( "hello2\n" );

// execl( "/bin/ls", "ls", NULL ); // (2)

printf( "exec not executed\n");
close( STDIN_FILENO );
dup2( fd[0], STDIN_FILENO );

close( fd[0] );
close( fd[1] );

char buf[100];

while( gets( buf ) != NULL )
printf( "message: %s\n", buf );

output when exec commented:

message: hello

message: hello2

message: exec not executed

when exec not commented:

message: filt1

message: filt1.d

.... other files

message: makefile



By default, stdio fully buffers output to a stream unless it's writing to a terminal (except for stderr, which is unbuffered). So the output to the pipe is being buffered.

When you call execl(), the memory of the current process is discarded and replaced with the program you're loading. This causes the stdio output buffers to be discarded, so they never get written to the pipe.

The simple solution is to call fflush(stdout); before calling execl().