The following code redirects stdout
to the write-end of a pipe, whose read-end I then read from.
// main.cpp
#include <cassert>
#include <iostream>
#include <unistd.h>
int main( int argc, char* argv[] ) {
int my_pipe[2] = { -1, -1 };
char buf[100] = { '\0' };
int stdout_copy;
assert( -1 != (stdout_copy = dup( STDOUT_FILENO )) );
assert( 0 == pipe( my_pipe ) );
assert( -1 != dup2( my_pipe[1], STDOUT_FILENO ) );
//close( my_pipe[1] ); // (1) Uncommenting this prevents hang.
//my_pipe[1] = -1;
std::cout << "hello"
//<< std::endl // (2) Uncommenting this also prevents hang.
;
assert( -1 != dup2( stdout_copy, STDOUT_FILENO ) );
read( my_pipe[0], buf, sizeof buf );
std::cout << buf;
close( my_pipe[0] );
return 0;
}
$ g++ --version && g++ -g ./main.cpp
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
Toying around with this code, I noticed that the read
hangs unless I either (1) close
my pipe's write-end after dup2
ing STDOUT_FILENO
to it, and/or (2) explicitly writing a std::endl
to std::cout
. Why is this so?
At first, I thought the issue had something to do with flushing of stdout
- which might've explained the need to explicitly write std::endl
, but (per my perhaps incomplete understanding) that doesn't explain why closing the write-end of the pipe would prevent the hang.
Update: I found this interesting: when both (1) and (2) are commented, std::cout << "hello\n";
does not prevent the hang; i.e. it's not "equivalent" to std::cout << "hello" << std::endl;
.