From 023fbe35ea61648cf709a7d02ae73999e5aeee60 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 17 Jan 2019 14:52:36 +0000 Subject: [PATCH] Tweaks to avoid a crash when asking for FGData path exit(-1) early in startup seems to cause QApplication to be cleaned up in a weird way --- src/GUI/SetupRootDialog.cxx | 12 +++++++++--- src/Main/fg_init.cxx | 5 ++++- src/Main/options.cxx | 23 ++++++++++++++++------- src/Main/options.hxx | 15 ++++++++------- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/GUI/SetupRootDialog.cxx b/src/GUI/SetupRootDialog.cxx index 685db1e61..789d88937 100755 --- a/src/GUI/SetupRootDialog.cxx +++ b/src/GUI/SetupRootDialog.cxx @@ -90,7 +90,7 @@ bool SetupRootDialog::runDialog(PromptState prompt) SetupRootDialog dlg(prompt); dlg.exec(); if (dlg.result() != QDialog::Accepted) { - exit(-1); + return false; } return true; @@ -104,7 +104,10 @@ SGPath SetupRootDialog::restoreUserSelectedRoot() bool ask = flightgear::checkKeyboardModifiersForSettingFGRoot(); if (ask || (path == QStringLiteral("!ask"))) { bool ok = runDialog(ManualChoiceRequested); - Q_ASSERT(ok); + if (!ok) { + exit(-1); + } + // run dialog either exit()s or sets fg_root, so this // behaviour is safe and correct. return globals->get_fg_root(); @@ -127,7 +130,10 @@ SGPath SetupRootDialog::restoreUserSelectedRoot() // okay, we don't have an acceptable FG_DATA anywhere we can find, we // have to ask the user what they want to do. bool ok = runDialog(VersionCheckFailed); - Q_ASSERT(ok); + if (!ok) { + exit(-1); + } + // run dialog either exit()s or sets fg_root, so this // behaviour is safe and correct. return globals->get_fg_root(); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 79fdf44af..147102837 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -640,7 +640,10 @@ int fgInitConfig ( int argc, char **argv, bool reinit ) fgSetDefaults(); flightgear::Options* options = flightgear::Options::sharedInstance(); if (!reinit) { - options->init(argc, argv, dataPath); + auto result = options->init(argc, argv, dataPath); + if (result != flightgear::FG_OPTIONS_OK) { + return result; + } } // establish default for developer-mode based upon compiled build types diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 27778a92e..ab27d3fbd 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -2098,7 +2098,7 @@ Options::~Options() { } -void Options::init(int argc, char **argv, const SGPath& appDataPath) +OptionResult Options::init(int argc, char** argv, const SGPath& appDataPath) { // first, process the command line bool inOptions = true; @@ -2143,8 +2143,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) } if (!p->shouldLoadDefaultConfig) { - setupRoot(argc, argv); - return; + return setupRoot(argc, argv); } // then config files @@ -2172,7 +2171,10 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) } // setup FG_ROOT - setupRoot(argc, argv); + auto res = setupRoot(argc, argv); + if (res != FG_OPTIONS_OK) { + return res; + } // system.fgfsrc is disabled, as we no longer allow anything in fgdata to set // fg-root/fg-home/fg-aircraft and hence control what files Nasal can access @@ -2202,6 +2204,8 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) "If you created this file intentionally, please move it to '" + nameForError + "'."); } + + return FG_OPTIONS_OK; } void Options::initPaths() @@ -2952,14 +2956,14 @@ string_list Options::extractOptions() const return result; } -void Options::setupRoot(int argc, char **argv) +OptionResult Options::setupRoot(int argc, char** argv) { SGPath root(globals->get_fg_root()); bool usingDefaultRoot = false; // root has already been set, so skip the fg_root setting and validation. if (!root.isNull()) { - return; + return FG_OPTIONS_OK; } if (isOptionSet("fg-root")) { @@ -2998,7 +3002,11 @@ void Options::setupRoot(int argc, char **argv) // a command-line, env-var or default root this check can fail and // we still want to use the GUI in that case if (versionComp != 0) { - SetupRootDialog::runDialog(usingDefaultRoot); + flightgear::initApp(argc, argv); + bool ok = SetupRootDialog::runDialog(usingDefaultRoot); + if (!ok) { + return FG_OPTIONS_EXIT; + } } #else SG_UNUSED(usingDefaultRoot); @@ -3022,6 +3030,7 @@ void Options::setupRoot(int argc, char **argv) std::string(FLIGHTGEAR_VERSION) + "' is required."); } #endif + return FG_OPTIONS_OK; } bool Options::shouldLoadDefaultConfig() const diff --git a/src/Main/options.hxx b/src/Main/options.hxx index c4a564563..5d0f72955 100644 --- a/src/Main/options.hxx +++ b/src/Main/options.hxx @@ -79,8 +79,8 @@ public: /** * pass command line arguments, read default config files */ - void init(int argc, char* argv[], const SGPath& appDataPath); - + OptionResult init(int argc, char* argv[], const SGPath& appDataPath); + /** * parse a config file (eg, .fgfsrc) */ @@ -188,15 +188,16 @@ private: void processArgResult(int result); - /** - * Setup the root base, and check it's valid. Bails out with exit(-1) if - * the root package was not found or is the incorrect version. Argv/argv + /** + * Setup the root base, and check it's valid. If + * the root package was not found or is the incorrect version, + * returns FG_OPTIONS_ERROR. Argv/argv * are passed since we might potentially show a GUI dialog at this point * to help the user our (finding a base package), and hence need to init Qt. */ - void setupRoot(int argc, char **argv); + OptionResult setupRoot(int argc, char** argv); + - class OptionsPrivate; std::unique_ptr p; };