aboutsummaryrefslogtreecommitdiff
path: root/build2/b.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-06-24 11:25:05 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-06-24 11:25:05 +0200
commit2ad6aa134d9e8e755c8c738d0b51d72b0851c212 (patch)
tree9d914797975e61350d41c9fdb71ee008b2aacdfc /build2/b.cxx
parent85399cf60764b0fe54d44d4a5bacb54feae8dd62 (diff)
Constrain access to options to build system driver main() only
Diffstat (limited to 'build2/b.cxx')
-rw-r--r--build2/b.cxx114
1 files changed, 70 insertions, 44 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index a64c5e2..0eb007c 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -67,6 +67,8 @@ using namespace std;
namespace build2
{
+ static options ops;
+
int
main (int argc, char* argv[]);
@@ -180,13 +182,13 @@ main (int argc, char* argv[])
}
#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.
-//
+ // 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 ()));
@@ -196,26 +198,24 @@ main (int argc, char* argv[])
}
#endif
- try
- {
- // 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.
- //
- // On Windows disable displaying error reporting dialog box for the current
- // and child processes unless we run serially. This way we avoid multiple
- // dialog boxes to potentially pop up.
- //
+ // 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.
+ if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
+ fail << "unable to ignore broken pipe (SIGPIPE) signal: "
+ << system_error (errno, generic_category ()); // Sanitize.
#endif
- // Parse the command line. We want to be able to specify options, vars,
- // and buildspecs in any order (it is really handy to just add -v at the
- // end of the command line).
+ // Parse the command line.
+ //
+ try
+ {
+ // We want to be able to specify options, vars, and buildspecs in any
+ // order (it is really handy to just add -v at the end of the command
+ // line).
//
strings cmd_vars;
string args;
@@ -336,29 +336,32 @@ main (int argc, char* argv[])
else
args += ')';
}
+
+ // Validate options.
+ //
+ if (ops.progress () && ops.no_progress ())
+ fail << "both --progress and --no-progress specified";
+
+ if (ops.mtime_check () && ops.no_mtime_check ())
+ fail << "both --mtime-check and --no-mtime-check specified";
}
catch (const cl::exception& e)
{
fail << e;
}
- // Validate options.
+ // Initialize the diagnostics state.
//
- if (ops.progress () && ops.no_progress ())
- fail << "both --progress and --no-progress specified";
-
- if (ops.mtime_check () && ops.no_mtime_check ())
- fail << "both --mtime-check and --no-mtime-check specified";
-
- // Global initializations.
- //
- stderr_term = fdterm (stderr_fd ());
- init (argv[0],
- ops.verbose_specified ()
- ? ops.verbose ()
- : ops.V () ? 3 : ops.v () ? 2 : ops.quiet () ? 0 : 1);
-
- // Version.
+ init_diag ((ops.verbose_specified ()
+ ? ops.verbose ()
+ : ops.V () ? 3 : ops.v () ? 2 : ops.quiet () ? 0 : 1),
+ (ops.progress () ? optional<bool> (true) :
+ ops.no_progress () ? optional<bool> (false) : nullopt),
+ ops.no_line (),
+ ops.no_column (),
+ fdterm (stderr_fd ()));
+
+ // Handle --version.
//
if (ops.version ())
{
@@ -370,7 +373,7 @@ main (int argc, char* argv[])
return 0;
}
- // Help.
+ // Handle --help.
//
if (ops.help ())
{
@@ -396,8 +399,33 @@ main (int argc, char* argv[])
}
}
+ // Initialize time conversion data that is used by localtime_r().
+ //
+#ifndef _WIN32
+ tzset ();
+#else
+ _tzset ();
+#endif
+
+ // Initialize the global state.
+ //
+ init (argv[0],
+ !ops.serial_stop (), ops.dry_run (),
+ (ops.mtime_check () ? optional<bool> (true) :
+ ops.no_mtime_check () ? optional<bool> (false) : nullopt),
+ (ops.config_sub_specified ()
+ ? optional<path> (ops.config_sub ())
+ : nullopt),
+ (ops.config_guess_specified ()
+ ? optional<path> (ops.config_guess ())
+ : nullopt));
+
#ifdef _WIN32
- if (!ops.serial_stop ())
+ // 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.
+ //
+ if (keep_going)
SetErrorMode (SetErrorMode (0) | // Returns the current mode.
SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#endif
@@ -450,8 +478,6 @@ main (int argc, char* argv[])
#endif
}
- keep_going = !ops.serial_stop ();
-
// Start up the scheduler and allocate lock shards.
//
size_t jobs (0);