aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/bpkg.cxx19
1 files changed, 19 insertions, 0 deletions
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx
index b5eaf7d..b93637c 100644
--- a/bpkg/bpkg.cxx
+++ b/bpkg/bpkg.cxx
@@ -10,6 +10,7 @@
#include <exception> // set_terminate(), terminate_handler
#include <type_traits> // enable_if, is_base_of
+#include <libbutl/fdstream.hxx> // std*_fdmode()
#include <libbutl/backtrace.hxx> // backtrace()
// Embedded build system driver.
@@ -607,6 +608,24 @@ try
default_terminate = set_terminate (custom_terminate);
+ // Note that the standard stream descriptors can potentially be in the
+ // non-blocking mode, which the C++ streams are not suited for and which are
+ // not fully supported by butl::iofdstreams. Using such descriptors may lead
+ // to various weird failures (see GH issue #417 for the reproducer). Thus,
+ // we just turn such descriptors into the blocking mode at the beginning of
+ // the program execution.
+ //
+ try
+ {
+ stdin_fdmode (fdstream_mode::blocking);
+ stdout_fdmode (fdstream_mode::blocking);
+ stderr_fdmode (fdstream_mode::blocking);
+ }
+ catch (const io_error& e)
+ {
+ fail << "unable to turn standard streams into blocking mode: " << e;
+ }
+
if (fdterm (stderr_fd ()))
{
stderr_term = std::getenv ("TERM");