aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/build/script/parser.test.cxx2
-rw-r--r--libbuild2/function.test.cxx2
-rw-r--r--libbuild2/make-parser.test.cxx2
-rw-r--r--libbuild2/test/script/parser.test.cxx2
-rw-r--r--libbuild2/utility.cxx87
-rw-r--r--libbuild2/utility.hxx14
6 files changed, 105 insertions, 4 deletions
diff --git a/libbuild2/build/script/parser.test.cxx b/libbuild2/build/script/parser.test.cxx
index 63d41ff..5808015 100644
--- a/libbuild2/build/script/parser.test.cxx
+++ b/libbuild2/build/script/parser.test.cxx
@@ -176,7 +176,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (nullptr, argv[0]);
+ init (nullptr, argv[0], true);
// Serial execution.
//
diff --git a/libbuild2/function.test.cxx b/libbuild2/function.test.cxx
index 0b3c922..f711d2f 100644
--- a/libbuild2/function.test.cxx
+++ b/libbuild2/function.test.cxx
@@ -44,7 +44,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (nullptr, argv[0]);
+ init (nullptr, argv[0], true);
// Serial execution.
//
diff --git a/libbuild2/make-parser.test.cxx b/libbuild2/make-parser.test.cxx
index 5c57978..00a265a 100644
--- a/libbuild2/make-parser.test.cxx
+++ b/libbuild2/make-parser.test.cxx
@@ -22,7 +22,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (nullptr, argv[0]);
+ init (nullptr, argv[0], true);
path_name in ("<stdin>");
diff --git a/libbuild2/test/script/parser.test.cxx b/libbuild2/test/script/parser.test.cxx
index eb4a59b..e0dd3d2 100644
--- a/libbuild2/test/script/parser.test.cxx
+++ b/libbuild2/test/script/parser.test.cxx
@@ -162,7 +162,7 @@ namespace build2
// Fake build system driver, default verbosity.
//
init_diag (1);
- init (nullptr, argv[0]);
+ init (nullptr, argv[0], true);
// Serial execution.
//
diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx
index 3f89def..31be3aa 100644
--- a/libbuild2/utility.cxx
+++ b/libbuild2/utility.cxx
@@ -3,8 +3,18 @@
#include <libbuild2/utility.hxx>
+#ifndef _WIN32
+# include <signal.h> // signal()
+#else
+# include <libbutl/win32-utility.hxx>
+#endif
+
#include <time.h> // tzset() (POSIX), _tzset() (Windows)
+#ifdef __GLIBCXX__
+# include <locale>
+#endif
+
#include <cerrno> // ENOENT
#include <cstring> // strlen(), str[n]cmp()
#include <iostream> // cerr
@@ -551,8 +561,73 @@ namespace build2
}
void
+ init_process ()
+ {
+ // This is a little hack to make out baseutils for Windows work when
+ // called with absolute path. In a nutshell, MSYS2's exec*p() doesn't
+ // search in the parent's executable directory, only in PATH. And since we
+ // are running without a shell (that would read /etc/profile which sets
+ // PATH to some sensible values), we are only getting Win32 PATH values.
+ // And MSYS2 /bin is not one of them. So what we are going to do is add
+ // /bin at the end of PATH (which will be passed as is by the MSYS2
+ // machinery). This will make MSYS2 search in /bin (where our baseutils
+ // live). And for everyone else this should be harmless since it is not a
+ // valid Win32 path.
+ //
+#ifdef _WIN32
+ {
+ string mp;
+ if (optional<string> p = getenv ("PATH"))
+ {
+ mp = move (*p);
+ mp += ';';
+ }
+ mp += "/bin";
+
+ setenv ("PATH", mp);
+ }
+#endif
+
+ // On POSIX ignore SIGPIPE which is signaled to a pipe-writing process if
+ // the pipe reading end is closed. Note that by default this signal
+ // terminates a process. Also note that there is no way to disable this
+ // behavior on a file descriptor basis or for the write() function call.
+ //
+#ifndef _WIN32
+ if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
+ fail << "unable to ignore broken pipe (SIGPIPE) signal: "
+ << system_error (errno, generic_category ()); // Sanitize.
+#endif
+
+ // Initialize time conversion data that is used by localtime_r().
+ //
+#ifndef _WIN32
+ tzset ();
+#else
+ _tzset ();
+#endif
+
+ // A data race happens in the libstdc++ (as of GCC 7.2) implementation of
+ // the ctype<char>::narrow() function (bug #77704). The issue is easily
+ // triggered by the testscript runner that indirectly (via regex) uses
+ // ctype<char> facet of the global locale (and can potentially be
+ // triggered by other locale-aware code). We work around this by
+ // pre-initializing the global locale facet internal cache.
+ //
+#ifdef __GLIBCXX__
+ {
+ const ctype<char>& ct (use_facet<ctype<char>> (locale ()));
+
+ for (size_t i (0); i != 256; ++i)
+ ct.narrow (static_cast<char> (i), '\0');
+ }
+#endif
+ }
+
+ void
init (void (*t) (bool),
const char* a0,
+ bool ss,
optional<bool> mc,
optional<path> cs,
optional<path> cg)
@@ -587,6 +662,18 @@ namespace build2
}
script::regex::init ();
+
+ if (!ss)
+ {
+#ifdef _WIN32
+ // On Windows disable displaying error reporting dialog box for the
+ // current and child processes unless we are in the stop mode. Failed
+ // that we may have multiple dialog boxes popping up.
+ //
+ SetErrorMode (SetErrorMode (0) | // Returns the current mode.
+ SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+#endif
+ }
}
optional<uint64_t>
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index b62d2ab..c82dcc2 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -97,6 +97,19 @@ namespace build2
//
using butl::path_pattern;
+ // Perform process-wide initializations/adjustments/workarounds. Should be
+ // called once early in main(). In particular, besides other things, this
+ // functions does the following:
+ //
+ // - Sets PATH to include baseutils /bin on Windows.
+ //
+ // - Ignores SIGPIPE.
+ //
+ // - Calls tzset().
+ //
+ LIBBUILD2_SYMEXPORT void
+ init_process ();
+
// Diagnostics state (verbosity level, etc; see <libbuild2/diagnostics.hxx>).
//
// Note on naming of values (here and in the global state below) that come
@@ -138,6 +151,7 @@ namespace build2
LIBBUILD2_SYMEXPORT void
init (void (*terminate) (bool),
const char* argv0,
+ bool serial_stop,
optional<bool> mtime_check = nullopt,
optional<path> config_sub = nullopt,
optional<path> config_guess = nullopt);