forked from qt-creator/qt-creator
LinuxDevice: Add disconnected state
Change-Id: Ic2c909e3375a9fb025a335c1ca65621fa031d000 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -878,52 +878,73 @@ QByteArray DesktopDeviceFileAccess::fileId(const FilePath &filePath) const
|
||||
|
||||
// UnixDeviceAccess
|
||||
|
||||
static Utils::unexpected<QString> make_unexpected_disconnected()
|
||||
{
|
||||
return make_unexpected(Tr::tr("Device is not connected"));
|
||||
}
|
||||
|
||||
UnixDeviceFileAccess::~UnixDeviceFileAccess() = default;
|
||||
|
||||
bool UnixDeviceFileAccess::runInShellSuccess(const CommandLine &cmdLine,
|
||||
const QByteArray &stdInData) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
return runInShell(cmdLine, stdInData).exitCode == 0;
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isExecutableFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-x", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isReadableFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-r", path, "-a", "-f", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isWritableFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-w", path, "-a", "-f", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isReadableDirectory(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-r", path, "-a", "-d", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isWritableDirectory(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-w", path, "-a", "-d", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-f", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::isDirectory(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
if (filePath.isRootPath())
|
||||
return true;
|
||||
|
||||
@@ -933,12 +954,16 @@ bool UnixDeviceFileAccess::isDirectory(const FilePath &filePath) const
|
||||
|
||||
bool UnixDeviceFileAccess::isSymLink(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-h", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::hasHardLinks(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QStringList args = statArgs(filePath, "%h", "%l");
|
||||
const RunResult result = runInShell({"stat", args, OsType::OsTypeLinux});
|
||||
return result.stdOut.toLongLong() > 1;
|
||||
@@ -946,29 +971,39 @@ bool UnixDeviceFileAccess::hasHardLinks(const FilePath &filePath) const
|
||||
|
||||
bool UnixDeviceFileAccess::ensureExistingFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"touch", {path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::createDirectory(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"mkdir", {"-p", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::exists(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
const QString path = filePath.path();
|
||||
return runInShellSuccess({"test", {"-e", path}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::removeFile(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
return runInShellSuccess({"rm", {filePath.path()}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::removeRecursively(const FilePath &filePath, QString *error) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
QTC_ASSERT(filePath.path().startsWith('/'), return false);
|
||||
|
||||
const QString path = filePath.cleanPath().path();
|
||||
@@ -989,6 +1024,8 @@ bool UnixDeviceFileAccess::removeRecursively(const FilePath &filePath, QString *
|
||||
expected_str<void> UnixDeviceFileAccess::copyFile(const FilePath &filePath,
|
||||
const FilePath &target) const
|
||||
{
|
||||
if (disconnected())
|
||||
return make_unexpected_disconnected();
|
||||
const RunResult result = runInShell(
|
||||
{"cp", {filePath.path(), target.path()}, OsType::OsTypeLinux});
|
||||
|
||||
@@ -1003,11 +1040,17 @@ expected_str<void> UnixDeviceFileAccess::copyFile(const FilePath &filePath,
|
||||
|
||||
bool UnixDeviceFileAccess::renameFile(const FilePath &filePath, const FilePath &target) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
|
||||
return runInShellSuccess({"mv", {filePath.path(), target.path()}, OsType::OsTypeLinux});
|
||||
}
|
||||
|
||||
FilePath UnixDeviceFileAccess::symLinkTarget(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
const RunResult result = runInShell(
|
||||
{"readlink", {"-n", "-e", filePath.path()}, OsType::OsTypeLinux});
|
||||
const QString out = QString::fromUtf8(result.stdOut);
|
||||
@@ -1018,6 +1061,9 @@ expected_str<QByteArray> UnixDeviceFileAccess::fileContents(const FilePath &file
|
||||
qint64 limit,
|
||||
qint64 offset) const
|
||||
{
|
||||
if (disconnected())
|
||||
return make_unexpected_disconnected();
|
||||
|
||||
QStringList args = {"if=" + filePath.path()};
|
||||
if (limit > 0 || offset > 0) {
|
||||
const qint64 gcd = std::gcd(limit, offset);
|
||||
@@ -1045,6 +1091,9 @@ expected_str<qint64> UnixDeviceFileAccess::writeFileContents(const FilePath &fil
|
||||
const QByteArray &data,
|
||||
qint64 offset) const
|
||||
{
|
||||
if (disconnected())
|
||||
return make_unexpected_disconnected();
|
||||
|
||||
QStringList args = {"of=" + filePath.path()};
|
||||
if (offset != 0) {
|
||||
args.append("bs=1");
|
||||
@@ -1061,6 +1110,9 @@ expected_str<qint64> UnixDeviceFileAccess::writeFileContents(const FilePath &fil
|
||||
|
||||
expected_str<FilePath> UnixDeviceFileAccess::createTempFile(const FilePath &filePath)
|
||||
{
|
||||
if (disconnected())
|
||||
return make_unexpected_disconnected();
|
||||
|
||||
if (!m_hasMkTemp.has_value())
|
||||
m_hasMkTemp = runInShellSuccess({"which", {"mktemp"}, OsType::OsTypeLinux});
|
||||
|
||||
@@ -1120,6 +1172,9 @@ expected_str<FilePath> UnixDeviceFileAccess::createTempFile(const FilePath &file
|
||||
|
||||
QDateTime UnixDeviceFileAccess::lastModified(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
const RunResult result = runInShell(
|
||||
{"stat", {"-L", "-c", "%Y", filePath.path()}, OsType::OsTypeLinux});
|
||||
qint64 secs = result.stdOut.toLongLong();
|
||||
@@ -1131,6 +1186,9 @@ QStringList UnixDeviceFileAccess::statArgs(const FilePath &filePath,
|
||||
const QString &linuxFormat,
|
||||
const QString &macFormat) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
return (filePath.osType() == OsTypeMac ? QStringList{"-f", macFormat}
|
||||
: QStringList{"-c", linuxFormat})
|
||||
<< "-L" << filePath.path();
|
||||
@@ -1138,6 +1196,9 @@ QStringList UnixDeviceFileAccess::statArgs(const FilePath &filePath,
|
||||
|
||||
QFile::Permissions UnixDeviceFileAccess::permissions(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
QStringList args = statArgs(filePath, "%a", "%p");
|
||||
|
||||
const RunResult result = runInShell({"stat", args, OsType::OsTypeLinux});
|
||||
@@ -1161,6 +1222,9 @@ QFile::Permissions UnixDeviceFileAccess::permissions(const FilePath &filePath) c
|
||||
|
||||
bool UnixDeviceFileAccess::setPermissions(const FilePath &filePath, QFile::Permissions perms) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
|
||||
const int flags = int(perms);
|
||||
return runInShellSuccess(
|
||||
{"chmod", {QString::number(flags, 16), filePath.path()}, OsType::OsTypeLinux});
|
||||
@@ -1168,6 +1232,9 @@ bool UnixDeviceFileAccess::setPermissions(const FilePath &filePath, QFile::Permi
|
||||
|
||||
qint64 UnixDeviceFileAccess::fileSize(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return -1;
|
||||
|
||||
const QStringList args = statArgs(filePath, "%s", "%z");
|
||||
const RunResult result = runInShell({"stat", args, OsType::OsTypeLinux});
|
||||
return result.stdOut.toLongLong();
|
||||
@@ -1175,12 +1242,18 @@ qint64 UnixDeviceFileAccess::fileSize(const FilePath &filePath) const
|
||||
|
||||
qint64 UnixDeviceFileAccess::bytesAvailable(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return -1;
|
||||
|
||||
const RunResult result = runInShell({"df", {"-k", filePath.path()}, OsType::OsTypeLinux});
|
||||
return FileUtils::bytesAvailableFromDFOutput(result.stdOut);
|
||||
}
|
||||
|
||||
QByteArray UnixDeviceFileAccess::fileId(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
const QStringList args = statArgs(filePath, "%D:%i", "%d:%i");
|
||||
|
||||
const RunResult result = runInShell({"stat", args, OsType::OsTypeLinux});
|
||||
@@ -1192,6 +1265,9 @@ QByteArray UnixDeviceFileAccess::fileId(const FilePath &filePath) const
|
||||
|
||||
FilePathInfo UnixDeviceFileAccess::filePathInfo(const FilePath &filePath) const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
if (filePath.path() == "/") // TODO: Add FilePath::isRoot()
|
||||
{
|
||||
const FilePathInfo r{4096,
|
||||
@@ -1218,6 +1294,9 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath,
|
||||
const FileFilter &filter,
|
||||
const FilePath::IterateDirCallback &callBack) const
|
||||
{
|
||||
if (disconnected())
|
||||
return false;
|
||||
|
||||
QTC_CHECK(filePath.isAbsolutePath());
|
||||
|
||||
CommandLine cmdLine{"find", filter.asFindArguments(filePath.path()), OsType::OsTypeLinux};
|
||||
@@ -1290,6 +1369,9 @@ void UnixDeviceFileAccess::findUsingLs(const QString ¤t,
|
||||
QStringList *found,
|
||||
const QString &start) const
|
||||
{
|
||||
if (disconnected())
|
||||
return;
|
||||
|
||||
const RunResult result = runInShell(
|
||||
{"ls", {"-1", "-a", "-p", "--", current}, OsType::OsTypeLinux});
|
||||
const QStringList entries = QString::fromUtf8(result.stdOut).split('\n', Qt::SkipEmptyParts);
|
||||
@@ -1349,6 +1431,9 @@ void UnixDeviceFileAccess::iterateDirectory(const FilePath &filePath,
|
||||
const FilePath::IterateDirCallback &callBack,
|
||||
const FileFilter &filter) const
|
||||
{
|
||||
if (disconnected())
|
||||
return;
|
||||
|
||||
// We try to use 'find' first, because that can filter better directly.
|
||||
// Unfortunately, it's not installed on all devices by default.
|
||||
if (m_tryUseFind) {
|
||||
@@ -1366,9 +1451,17 @@ void UnixDeviceFileAccess::iterateDirectory(const FilePath &filePath,
|
||||
|
||||
Environment UnixDeviceFileAccess::deviceEnvironment() const
|
||||
{
|
||||
if (disconnected())
|
||||
return {};
|
||||
|
||||
const RunResult result = runInShell({"env", {}, OsType::OsTypeLinux});
|
||||
const QString out = QString::fromUtf8(result.stdOut);
|
||||
return Environment(out.split('\n', Qt::SkipEmptyParts), OsTypeLinux);
|
||||
}
|
||||
|
||||
bool UnixDeviceFileAccess::disconnected() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
Reference in New Issue
Block a user