aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-09-04 13:49:48 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-09-04 13:49:48 +0300
commit019313915d5de12d7402db57df4a38f0cf778a33 (patch)
tree86643b35547b7ac31ec880a12a047f2981c29c23
parent1b6af2139940f2a8faa6e88c5ad9dffaa01a1021 (diff)
Turn standard streams into blocking mode on start (GH issue 417)
-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");