#include <iostream>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int main(){
// Make stdin non-blocking
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
printf("stdout O_NONBLOCK is: %d\n", fcntl(STDOUT_FILENO, F_GETFL) & O_NONBLOCK);
printf("stdin O_NONBLOCK is: %d\n", fcntl(STDIN_FILENO , F_GETFL) & O_NONBLOCK);
for(int i=0; i<16; i++){
cout<<" "<<"fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er "<<endl;
}
bool cerrfail=cerr.fail(), coutfail=cout.fail();
flush(cout); flush(clog); flush(cerr);
cout.clear(); cerr.clear(); clog.clear();
cerr<<"\ncerr.fail():"<<cerrfail<<" cout.fail():"<<coutfail<<endl;
}
possible output:
Compiler G++ 9.3
MacOS Mojave 10.14.6
stdout O_NONBLOCK is: 4
stdin O_NONBLOCK is: 4
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo ero
cerr.fail():0 cout.fail():1
fails because of fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
Why? How to fix keeping stdin non-block?
update. Why? because setting stdin O_NONBLOCK also makes stdout O_NONBLOCK. And std::out receives some ASYNC error code (like ETRYAGAIN) in its internals.
I see two solutions:
update2. The issue appears on MacOS only. Does not on Linux amd64 and does not on Linux MIPS (Atheros).
Standard streams do not support non-blocking file descriptors, those are beyond the scope of the C++ standard.
If you insist on using non-blocking file descriptors with standard streams, then you need to implement a stream buffer that can read/write non-blocking file descriptors. You can do that from scratch by deriving std::basic_streambuf
and implementing its virtual functions or use excellent Boost.Iostreams
to greatly reduce the amount and complexity of boilerplate code you'd otherwise have to write. And then replace the buffer of std::cout
, std::cin
and friends with your special stream buffer with a call to std::basic_ios<>::rdbuf
.
Even then, using std::istream
and std::ostream
interfaces you wouldn't be able to distinguish end-of-file from EAGAIN
.
You may like to elaborate what problem you are trying to solve because your current solution creates more problems.