mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 01:05:34 +08:00
Avoid long "hanging" if Windows UNC path is not reachable
Use own "isDirExisting" function checking UNC paths
This commit is contained in:
@@ -203,8 +203,7 @@ namespace BlackCore
|
||||
{
|
||||
// ever used with XPlane
|
||||
const QString pluginDir = CXPlaneUtil::pluginDirFromRootDir(m_simulatorSettings.getSimulatorDirectoryOrDefault(CSimulatorInfo::XPLANE));
|
||||
const QDir dir(pluginDir);
|
||||
if (dir.exists())
|
||||
if (CDirectoryUtils::isDirExisting(pluginDir))
|
||||
{
|
||||
// only check if we are on a XP machine
|
||||
const QStringList conflicts = CXPlaneUtil::findConflictingPlugins(pluginDir);
|
||||
|
||||
@@ -479,7 +479,7 @@ namespace BlackCore
|
||||
if (part2 == "show")
|
||||
{
|
||||
const QDir dir(CInterpolationLogger::getLogDirectory());
|
||||
if (dir.exists())
|
||||
if (CDirectoryUtils::isDirExisting(dir))
|
||||
{
|
||||
const QUrl dirUrl = QUrl::fromLocalFile(dir.absolutePath());
|
||||
QDesktopServices::openUrl(dirUrl); // show dir in browser
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
//! \cond PRIVATE
|
||||
|
||||
#include "blackmisc/directoryutils.h"
|
||||
#include "blackmisc/fileutils.h"
|
||||
#include "blackmisc/range.h"
|
||||
#include "directoryutils.h"
|
||||
#include "fileutils.h"
|
||||
#include "range.h"
|
||||
#include "blackconfig/buildconfig.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
@@ -416,7 +416,7 @@ namespace BlackMisc
|
||||
{
|
||||
if (testDir.isEmpty()) { return false; }
|
||||
const QDir dir(testDir);
|
||||
if (!dir.exists()) { return false; }
|
||||
if (!CDirectoryUtils::isDirExisting(dir)) { return false; }
|
||||
return !dir.isEmpty();
|
||||
}
|
||||
|
||||
@@ -438,6 +438,33 @@ namespace BlackMisc
|
||||
return dirs;
|
||||
}
|
||||
|
||||
bool CDirectoryUtils::isDirExisting(const QString &path)
|
||||
{
|
||||
if (!CBuildConfig::isRunningOnWindowsNtPlatform())
|
||||
{
|
||||
const QDir dir(path);
|
||||
return dir.exists();
|
||||
}
|
||||
|
||||
// Windows
|
||||
if (!CFileUtils::isWindowsUncPath(path))
|
||||
{
|
||||
const QDir dir(path);
|
||||
return dir.exists();
|
||||
}
|
||||
const QString machine(CFileUtils::windowsUncMachine(path));
|
||||
if (!CFileUtils::canPingUncMachine(machine)) { return false; }
|
||||
|
||||
const QDir dir(path);
|
||||
return dir.exists();
|
||||
}
|
||||
|
||||
bool CDirectoryUtils::isDirExisting(const QDir &dir)
|
||||
{
|
||||
if (!CFileUtils::isWindowsUncPath(dir.absolutePath())) { return dir.exists(); }
|
||||
return CDirectoryUtils::isDirExisting(dir.absolutePath());
|
||||
}
|
||||
|
||||
QSet<QString> CDirectoryUtils::fileNamesToQSet(const QFileInfoList &fileInfoList)
|
||||
{
|
||||
QSet<QString> sl;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFileInfoList>
|
||||
|
||||
namespace BlackMisc
|
||||
@@ -144,6 +145,14 @@ namespace BlackMisc
|
||||
//! Get the existing directories
|
||||
static QStringList getExistingUnemptyDirectories(const QStringList &directories);
|
||||
|
||||
//! Directory existing? Also checking UNC paths upfront.
|
||||
//! \remark Motivation: if an UNC cannot be accessed (e.g. machine is down) it can take very long before functions like QDir respond
|
||||
//! \remark for non-UNC paths it is the same as the QDir checks
|
||||
//! @{
|
||||
static bool isDirExisting(const QString &path);
|
||||
static bool isDirExisting(const QDir &dir);
|
||||
//! @}
|
||||
|
||||
//! Result of directory comparison
|
||||
struct DirComparison
|
||||
{
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "blackmisc/network/networkutils.h"
|
||||
#include "blackmisc/math/mathutils.h"
|
||||
#include "blackmisc/worker.h"
|
||||
#include "blackmisc/fileutils.h"
|
||||
#include "blackmisc/math/mathutils.h"
|
||||
#include "blackconfig/buildconfig.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
@@ -21,10 +22,12 @@
|
||||
#include <QLockFile>
|
||||
#include <QTextStream>
|
||||
#include <QtGlobal>
|
||||
#include <QMap>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace BlackConfig;
|
||||
using namespace BlackMisc::Math;
|
||||
using namespace BlackMisc::Network;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -383,6 +386,59 @@ namespace BlackMisc
|
||||
return fixedPaths;
|
||||
}
|
||||
|
||||
bool CFileUtils::isWindowsUncPath(const QString &filePath)
|
||||
{
|
||||
if (filePath.startsWith("//") || filePath.startsWith("\\\\")) { return true; }
|
||||
if (!CBuildConfig::isRunningOnWindowsNtPlatform()) { return false; } // "/tmp" is valid on Unix/Mac
|
||||
|
||||
// Windows here
|
||||
const QString fp = fixWindowsUncPath(filePath);
|
||||
return (fp.startsWith("//") || fp.startsWith("\\\\"));
|
||||
}
|
||||
|
||||
QString CFileUtils::windowsUncMachine(const QString &filePath)
|
||||
{
|
||||
if (!CFileUtils::isWindowsUncPath(filePath)) { return QStringLiteral(""); }
|
||||
QString f = filePath;
|
||||
f.replace("\\", "/");
|
||||
f.replace("//", "");
|
||||
if (f.startsWith("/")) { f = f.mid(1); }
|
||||
const int i = f.indexOf('/');
|
||||
if (i < 0) { return f; }
|
||||
return f.left(i);
|
||||
}
|
||||
|
||||
bool CFileUtils::canPingUncMachine(const QString &machine)
|
||||
{
|
||||
static QMap<QString, qint64> good;
|
||||
static QMap<QString, qint64> bad;
|
||||
|
||||
if (machine.isEmpty()) { return false; }
|
||||
const QString m = machine.toLower();
|
||||
if (good.contains(m)) { return true; } // good ones we only test once
|
||||
if (bad.contains(m))
|
||||
{
|
||||
const qint64 ts = bad.value(m);
|
||||
const qint64 dt = QDateTime::currentSecsSinceEpoch() - ts;
|
||||
if (dt < 1000 * 60) { return false; } // still bad
|
||||
|
||||
// outdated, test again
|
||||
}
|
||||
|
||||
const bool p = CNetworkUtils::canPing(m);
|
||||
if (p)
|
||||
{
|
||||
good.insert(m, QDateTime::currentSecsSinceEpoch());
|
||||
bad.remove(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
bad.insert(m, QDateTime::currentSecsSinceEpoch());
|
||||
good.remove(m);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
QString CFileUtils::toWindowsLocalPath(const QString &path)
|
||||
{
|
||||
QString p = CFileUtils::fixWindowsUncPath(path);
|
||||
|
||||
@@ -147,6 +147,15 @@ namespace BlackMisc
|
||||
//! Fix UNC file paths
|
||||
static QStringList fixWindowsUncPaths(const QStringList &filePaths);
|
||||
|
||||
//! Windows UNC path?
|
||||
static bool isWindowsUncPath(const QString &filePath);
|
||||
|
||||
//! Machine in Windows UNC path
|
||||
static QString windowsUncMachine(const QString &filePath);
|
||||
|
||||
//! Can connect the UNC machine
|
||||
static bool canPingUncMachine(const QString &machine);
|
||||
|
||||
//! To Windows path using "\" delimiter
|
||||
static QString toWindowsLocalPath(const QString &path);
|
||||
|
||||
|
||||
@@ -74,7 +74,14 @@ namespace BlackMisc
|
||||
}
|
||||
process.start();
|
||||
process.waitForFinished();
|
||||
return process.exitCode() == 0;
|
||||
const int rc = process.exitCode();
|
||||
if (rc != 0) { return false; }
|
||||
|
||||
const QString std = process.readAllStandardOutput();
|
||||
const QString err = process.readAllStandardError();
|
||||
if (std.contains("unreachable", Qt::CaseInsensitive)) { return false; }
|
||||
if (err.contains("unreachable", Qt::CaseInsensitive)) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CNetworkUtils::canPing(const CUrl &url)
|
||||
@@ -92,7 +99,7 @@ namespace BlackMisc
|
||||
if (address.isNull()) { continue; }
|
||||
if (address.protocol() == QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
QString a = address.toString();
|
||||
const QString a = address.toString();
|
||||
ips.append(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ namespace BlackMisc
|
||||
QStringList CXPlaneUtil::pluginSubdirectories(const QString &pluginDir)
|
||||
{
|
||||
const QString dirName = pluginDir.isEmpty() ? xplaneRootDir() : pluginDir;
|
||||
if (!CDirectoryUtils::isDirExisting(dirName)) { return QStringList(); }
|
||||
const QDir dir(dirName);
|
||||
if (!dir.exists()) { return QStringList(); }
|
||||
return dir.entryList(QDir::Dirs, QDir::Name | QDir::IgnoreCase);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace BlackMisc
|
||||
if (!rootDir.isEmpty())
|
||||
{
|
||||
const QString xswiftbusDir = CFileUtils::appendFilePathsAndFixUnc(CXPlaneUtil::pluginDirFromRootDir(xplaneRootDir), CXPlaneUtil::xswiftbusPathName());
|
||||
if (QDir(xswiftbusDir).exists())
|
||||
if (CDirectoryUtils::isDirExisting(xswiftbusDir))
|
||||
{
|
||||
return xswiftbusDir;
|
||||
}
|
||||
@@ -197,7 +197,7 @@ namespace BlackMisc
|
||||
if (!rootDir.isEmpty())
|
||||
{
|
||||
const QString xswiftbusLegacy = CFileUtils::appendFilePathsAndFixUnc(xplaneRootDir, legacyPath);
|
||||
if (QDir(xswiftbusLegacy).exists())
|
||||
if (CDirectoryUtils::isDirExisting(xswiftbusLegacy))
|
||||
{
|
||||
return xswiftbusLegacy;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user