diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2022-02-21 09:16:20 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2022-02-21 09:16:20 +0200 |
commit | c397402cba2f8bccaa9b8e63f7ae95f3540f54cd (patch) | |
tree | fd20bc9d0cfc69efc8f9d6975bf893d9c352565d /libbuild2 | |
parent | 995cd7946bf605804603fe79c6cef1ddf6db83b5 (diff) |
Factor process-wide initialization to init_process() function
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/build/script/parser.test.cxx | 2 | ||||
-rw-r--r-- | libbuild2/function.test.cxx | 2 | ||||
-rw-r--r-- | libbuild2/make-parser.test.cxx | 2 | ||||
-rw-r--r-- | libbuild2/test/script/parser.test.cxx | 2 | ||||
-rw-r--r-- | libbuild2/utility.cxx | 87 | ||||
-rw-r--r-- | libbuild2/utility.hxx | 14 |
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); |