From aa8a7b3e8a7b7a483a4644864fe29df41f26606e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 23 Sep 2019 20:37:58 +0300 Subject: [PATCH] Make errors in Emu::Init verbose and don't crash Allow TTY.log to be disabled if file access failed Add fs::error::isdir --- Utilities/File.cpp | 4 +- Utilities/File.h | 1 + rpcs3/Emu/System.cpp | 75 ++++++++++++++++++++++++++----------- rpcs3/rpcs3qt/log_frame.cpp | 16 +++++--- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index d7afb64f12..76c71831d4 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -154,6 +154,7 @@ static fs::error to_error(int e) case EACCES: return fs::error::acces; case ENOTEMPTY: return fs::error::notempty; case EROFS: return fs::error::readonly; + case EISDIR: return fs::error::isdir; default: fmt::throw_exception("Unknown system error: %d.", e); } } @@ -1572,7 +1573,7 @@ bool fs::remove_all(const std::string& path, bool remove_root) { return false; } - + if (remove_root) { return remove_dir(path); @@ -1753,6 +1754,7 @@ void fmt_class_string::format(std::string& out, u64 arg) case fs::error::acces: return "Access violation"; case fs::error::notempty: return "Not empty"; case fs::error::readonly: return "Read only"; + case fs::error::isdir: return "Is a directory"; } return unknown; diff --git a/Utilities/File.h b/Utilities/File.h index d28dca19ce..5f805d438b 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -519,6 +519,7 @@ namespace fs acces, notempty, readonly, + isdir, }; // Error code returned diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 21ddc1c1f2..0039d546eb 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -312,7 +312,13 @@ void Emulator::Init() if (!g_tty) { - g_tty.open(fs::get_cache_dir() + "TTY.log", fs::rewrite + fs::append); + const auto tty_path = fs::get_cache_dir() + "TTY.log"; + g_tty.open(tty_path, fs::rewrite + fs::append); + + if (!g_tty) + { + LOG_FATAL(GENERAL, "Failed to create TTY log: %s (%s)", tty_path, fs::g_tls_error); + } } idm::init(); @@ -324,7 +330,16 @@ void Emulator::Init() g_cfg_defaults = g_cfg.to_string(); // Reload global configuration - g_cfg.from_string(fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::create).to_string()); + const auto cfg_path = fs::get_config_dir() + "/config.yml"; + + if (const fs::file cfg_file{cfg_path, fs::read + fs::create}) + { + g_cfg.from_string(cfg_file.to_string()); + } + else + { + LOG_FATAL(GENERAL, "Failed to access global config: %s (%s)", cfg_path, fs::g_tls_error); + } // Create directories (can be disabled if necessary) const std::string emu_dir = GetEmuDir(); @@ -332,30 +347,46 @@ void Emulator::Init() const std::string dev_hdd1 = fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir); const std::string dev_usb = fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir); + auto make_path_verbose = [](const std::string& path) + { + if (!fs::create_path(path)) + { + LOG_FATAL(GENERAL, "Failed to create path: %s (%s)", path, fs::g_tls_error); + } + }; + if (g_cfg.vfs.init_dirs) { - fs::create_path(dev_hdd0); - fs::create_path(dev_hdd1); - fs::create_path(dev_usb); - fs::create_dir(dev_hdd0 + "game/"); - fs::create_dir(dev_hdd0 + "game/TEST12345/"); - fs::create_dir(dev_hdd0 + "game/TEST12345/USRDIR/"); - fs::create_dir(dev_hdd0 + "game/.locks/"); - fs::create_dir(dev_hdd0 + "home/"); - fs::create_dir(dev_hdd0 + "home/" + m_usr + "/"); - fs::create_dir(dev_hdd0 + "home/" + m_usr + "/exdata/"); - fs::create_dir(dev_hdd0 + "home/" + m_usr + "/savedata/"); - fs::create_dir(dev_hdd0 + "home/" + m_usr + "/trophy/"); - fs::write_file(dev_hdd0 + "home/" + m_usr + "/localusername", fs::create + fs::excl + fs::write, "User"s); - fs::create_dir(dev_hdd0 + "disc/"); - fs::create_dir(dev_hdd0 + "savedata/"); - fs::create_dir(dev_hdd0 + "savedata/vmc/"); - fs::create_dir(dev_hdd1 + "cache/"); - fs::create_dir(dev_hdd1 + "game/"); + make_path_verbose(dev_hdd0); + make_path_verbose(dev_hdd1); + make_path_verbose(dev_usb); + make_path_verbose(dev_hdd0 + "game/"); + make_path_verbose(dev_hdd0 + "game/TEST12345/"); + make_path_verbose(dev_hdd0 + "game/TEST12345/USRDIR/"); + make_path_verbose(dev_hdd0 + "game/.locks/"); + make_path_verbose(dev_hdd0 + "home/"); + make_path_verbose(dev_hdd0 + "home/" + m_usr + "/"); + make_path_verbose(dev_hdd0 + "home/" + m_usr + "/exdata/"); + make_path_verbose(dev_hdd0 + "home/" + m_usr + "/savedata/"); + make_path_verbose(dev_hdd0 + "home/" + m_usr + "/trophy/"); + + if (!fs::write_file(dev_hdd0 + "home/" + m_usr + "/localusername", fs::create + fs::excl + fs::write, "User"s)) + { + if (fs::g_tls_error != fs::error::exist) + { + LOG_FATAL(GENERAL, "Failed to create file: %shome/%s/localusername (%s)", dev_hdd0, m_usr, fs::g_tls_error); + } + } + + make_path_verbose(dev_hdd0 + "disc/"); + make_path_verbose(dev_hdd0 + "savedata/"); + make_path_verbose(dev_hdd0 + "savedata/vmc/"); + make_path_verbose(dev_hdd1 + "cache/"); + make_path_verbose(dev_hdd1 + "game/"); } - fs::create_path(fs::get_cache_dir() + "shaderlog/"); - fs::create_path(fs::get_config_dir() + "captures/"); + make_path_verbose(fs::get_cache_dir() + "shaderlog/"); + make_path_verbose(fs::get_config_dir() + "captures/"); #ifdef WITH_GDB_DEBUGGER LOG_SUCCESS(GENERAL, "GDB debug server will be started and listening on %d upon emulator boot", (int)g_cfg.misc.gdb_server_port); diff --git a/rpcs3/rpcs3qt/log_frame.cpp b/rpcs3/rpcs3qt/log_frame.cpp index ccf766cb27..c4a3d585d7 100644 --- a/rpcs3/rpcs3qt/log_frame.cpp +++ b/rpcs3/rpcs3qt/log_frame.cpp @@ -225,7 +225,7 @@ void log_frame::CreateAndConnectActions() m_clearTTYAct = new QAction(tr("Clear"), this); connect(m_clearTTYAct, &QAction::triggered, m_tty, &QTextEdit::clear); - + m_stackAct_tty = new QAction(tr("Stack Mode (TTY)"), this); m_stackAct_tty->setCheckable(true); connect(m_stackAct_tty, &QAction::toggled, xgui_settings.get(), [=](bool checked) @@ -352,9 +352,13 @@ void log_frame::CreateAndConnectActions() { text = fmt::format("%s > %s\n", "Ch.%d", m_tty_channel, text); } - g_tty_size -= (1ll << 48); - g_tty.write(text.c_str(), text.size()); - g_tty_size += (1ll << 48) + text.size(); + + if (g_tty) + { + g_tty_size -= (1ll << 48); + g_tty.write(text.c_str(), text.size()); + g_tty_size += (1ll << 48) + text.size(); + } m_tty_input->clear(); }); @@ -449,7 +453,7 @@ void log_frame::UpdateUI() const auto start = steady_clock::now(); // Check TTY logs - while (const u64 size = std::max(0, g_tty_size.load() - m_tty_file.pos())) + while (const u64 size = std::max(0, g_tty_size.load() - (m_tty_file ? m_tty_file.pos() : 0))) { std::string buf; buf.resize(size); @@ -480,7 +484,7 @@ void log_frame::UpdateUI() std::stringstream buf_stream; buf_stream.str(buf); std::string buf_line; - while (std::getline(buf_stream, buf_line)) + while (std::getline(buf_stream, buf_line)) { QString suffix; QString tty_text = QString::fromStdString(buf_line);