Improve error message when daemonizing failed

PR #19959.
This commit is contained in:
Chocobo1 2023-11-21 14:05:32 +08:00 committed by GitHub
parent 137df132e8
commit 6f7f418ec1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 21 deletions

View file

@ -292,7 +292,8 @@ Application::Application(int &argc, char **argv)
connect(this, &QGuiApplication::commitDataRequest, this, &Application::shutdownCleanup, Qt::DirectConnection); connect(this, &QGuiApplication::commitDataRequest, this, &Application::shutdownCleanup, Qt::DirectConnection);
#endif #endif
LogMsg(tr("qBittorrent %1 started", "qBittorrent v3.2.0alpha started").arg(QStringLiteral(QBT_VERSION))); LogMsg(tr("qBittorrent %1 started. Process ID: %2", "qBittorrent v3.2.0alpha started")
.arg(QStringLiteral(QBT_VERSION), QString::number(QCoreApplication::applicationPid())));
if (portableModeEnabled) if (portableModeEnabled)
{ {
LogMsg(tr("Running in portable mode. Auto detected profile folder at: %1").arg(profileDir.toString())); LogMsg(tr("Running in portable mode. Auto detected profile folder at: %1").arg(profileDir.toString()));
@ -944,7 +945,7 @@ int Application::exec()
return BaseApplication::exec(); return BaseApplication::exec();
} }
bool Application::isRunning() bool Application::hasAnotherInstance() const
{ {
return !m_instanceManager->isFirstInstance(); return !m_instanceManager->isFirstInstance();
} }

View file

@ -101,7 +101,7 @@ public:
int exec(); int exec();
bool isRunning(); bool hasAnotherInstance() const;
bool callMainInstance(); bool callMainInstance();
const QBtCommandLineParameters &commandLineArgs() const; const QBtCommandLineParameters &commandLineArgs() const;

View file

@ -73,6 +73,7 @@ Q_IMPORT_PLUGIN(QICOPlugin)
#endif // DISABLE_GUI #endif // DISABLE_GUI
#include "base/global.h" #include "base/global.h"
#include "base/logger.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "base/profile.h" #include "base/profile.h"
#include "base/version.h" #include "base/version.h"
@ -125,7 +126,7 @@ int main(int argc, char *argv[])
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// QCoreApplication::applicationDirPath() needs an Application object instantiated first // QCoreApplication::applicationDirPath() needs an Application object instantiated first
// Let's hope that there won't be a crash before this line // Let's hope that there won't be a crash before this line
const char *envName = "_NT_SYMBOL_PATH"; const char envName[] = "_NT_SYMBOL_PATH";
const QString envValue = qEnvironmentVariable(envName); const QString envValue = qEnvironmentVariable(envName);
if (envValue.isEmpty()) if (envValue.isEmpty())
qputenv(envName, Application::applicationDirPath().toLocal8Bit()); qputenv(envName, Application::applicationDirPath().toLocal8Bit());
@ -185,13 +186,13 @@ int main(int argc, char *argv[])
setCurrentMigrationVersion(); setCurrentMigrationVersion();
} }
// Check if qBittorrent is already running for this user // Check if qBittorrent is already running
if (app->isRunning()) if (app->hasAnotherInstance())
{ {
#if defined(DISABLE_GUI) && !defined(Q_OS_WIN) #if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
if (params.shouldDaemonize) if (params.shouldDaemonize)
{ {
throw CommandLineParameterError(QCoreApplication::translate("Main", "You cannot use %1: qBittorrent is already running for this user.") throw CommandLineParameterError(QCoreApplication::translate("Main", "You cannot use %1: qBittorrent is already running.")
.arg(u"-d (or --daemon)"_s)); .arg(u"-d (or --daemon)"_s));
} }
#endif #endif
@ -221,8 +222,7 @@ int main(int argc, char *argv[])
// Since Apple made difficult for users to set PATH, we set here for convenience. // Since Apple made difficult for users to set PATH, we set here for convenience.
// Users are supposed to install Homebrew Python for search function. // Users are supposed to install Homebrew Python for search function.
// For more info see issue #5571. // For more info see issue #5571.
QByteArray path = "/usr/local/bin:"; const QByteArray path = "/usr/local/bin:" + qgetenv("PATH");
path += qgetenv("PATH");
qputenv("PATH", path.constData()); qputenv("PATH", path.constData());
// On OS X the standard is to not show icons in the menus // On OS X the standard is to not show icons in the menus
@ -235,19 +235,27 @@ int main(int argc, char *argv[])
#if defined(DISABLE_GUI) && !defined(Q_OS_WIN) #if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
if (params.shouldDaemonize) if (params.shouldDaemonize)
{ {
app.reset(); // Destroy current application app.reset(); // Destroy current application instance
if (daemon(1, 0) == 0) if (::daemon(1, 0) == 0)
{ {
app = std::make_unique<Application>(argc, argv); app = std::make_unique<Application>(argc, argv);
if (app->isRunning()) if (app->hasAnotherInstance())
{ {
// Another instance had time to start. // It is undefined behavior to write to log file since there is another qbt instance
// in play. But we still do it since there is chance that the log message will survive.
const QString errorMessage = QCoreApplication::translate("Main", "Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.")
.arg(QString::number(QCoreApplication::applicationPid()));
LogMsg(errorMessage, Log::CRITICAL);
// stdout, stderr is closed so we can't use them
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
else else
{ {
qCritical("Something went wrong while daemonizing, exiting..."); const QString errorMessage = QCoreApplication::translate("Main", "Error when daemonizing. Reason: \"%1\". Error code: %2.")
.arg(QString::fromLocal8Bit(strerror(errno)), QString::number(errno));
LogMsg(errorMessage, Log::CRITICAL);
qCritical("%s", qUtf8Printable(errorMessage));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }

View file

@ -31,8 +31,6 @@
#include "os.h" #include "os.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <memory>
#include <windows.h> #include <windows.h>
#include <powrprof.h> #include <powrprof.h>
#include <shlobj.h> #include <shlobj.h>
@ -87,11 +85,9 @@ void Utils::OS::shutdownComputer([[maybe_unused]] const ShutdownDialogAction &ac
} }
else else
{ {
const QString msg = QCoreApplication::translate("misc" std::wstring msg = QCoreApplication::translate("misc"
, "qBittorrent will shutdown the computer now because all downloads are complete."); , "qBittorrent will shutdown the computer now because all downloads are complete.").toStdWString();
auto msgWchar = std::make_unique<wchar_t[]>(msg.length() + 1); ::InitiateSystemShutdownW(nullptr, msg.data(), 10, TRUE, FALSE);
msg.toWCharArray(msgWchar.get());
::InitiateSystemShutdownW(nullptr, msgWchar.get(), 10, TRUE, FALSE);
} }
// Disable shutdown privilege. // Disable shutdown privilege.