diff --git a/basestruct/utils.cpp b/basestruct/utils.cpp index 0f398967..fdb8ca60 100644 --- a/basestruct/utils.cpp +++ b/basestruct/utils.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -86,12 +86,37 @@ int Utils::executCmd(const QString &strCmd, QString &outPut, QString &error) return exitcode; } -int Utils::executWithPipeCmd(const QString &strCmd, QString &outPut, QString &error) +int Utils::executWithInputOutputCmd(const QString &strCmd, const QStringList &strArg, const QString *inPut, QString &outPut, QString &error) { - QStringList argList; - argList << "-c" << strCmd; + qDebug() << "Entering Utils::executWithInputOutputCmd with command:" << strCmd << strArg; + QProcess proc; + int exitCode; + + proc.start(strCmd, strArg); + + // 统一等待启动完成:无论是否需要写入 stdin,都检测 FailedToStart + // (程序不存在等场景),避免后续 readAll 取到空输出且 exitCode 为 0 的"假成功" + if (!proc.waitForStarted(-1)) { + error = proc.errorString(); + return -1; + } + + if (inPut) { + proc.write(inPut->toLocal8Bit()); + proc.closeWriteChannel(); + } + + proc.waitForFinished(-1); + outPut = proc.readAllStandardOutput().data(); + // 优先取子进程 stderr(含 cryptsetup/xfs_db 等的真实失败原因); + // 为空时回退到 QProcess 自身错误(如启动失败 execvp: ...) + QString stdErr = proc.readAllStandardError(); + error = stdErr.isEmpty() ? proc.errorString() : stdErr; + exitCode = proc.exitCode(); + proc.close(); - return executeCmdWithArtList("/bin/bash", argList, outPut, error); + qDebug() << "Utils::executWithInputOutputCmd exitCode: " << exitCode; + return exitCode; } int Utils::executWithErrorCmd(const QString &strCmd, const QStringList &strArg, QString &outPut, QString &outPutError, QString &error) diff --git a/basestruct/utils.h b/basestruct/utils.h index 47113f60..28f3c85b 100644 --- a/basestruct/utils.h +++ b/basestruct/utils.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -55,13 +55,15 @@ class Utils static int executCmd(const QString &strCmd); /** - * @brief 执行外部命令,使用 /bin/bash -c 执行管道命令 + * @brief 执行外部命令,并提供输入输出 * @param strCmd:命令 + * @param strArg:参数 + * @param inPut:命令输入 * @param outPut:命令输出 * @param error:错误信息 * @return 非0失败 */ - static int executWithPipeCmd(const QString &strCmd, QString &outPut, QString &error); + static int executWithInputOutputCmd(const QString &strCmd, const QStringList &strArg, const QString *inPut, QString &outPut, QString &error); /** * @brief 执行外部命令 diff --git a/service/diskoperation/DeviceStorage.cpp b/service/diskoperation/DeviceStorage.cpp index 6fe1896a..cb3fd798 100755 --- a/service/diskoperation/DeviceStorage.cpp +++ b/service/diskoperation/DeviceStorage.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -504,14 +504,18 @@ void DeviceStorage::getDiskInfoModel(const QString &devicePath, QString &model) } } - cmd = "udevadm info " + devicePath + " | grep ID_MODEL="; - proc.start("bash", QStringList() << "-c" << cmd); + proc.start("udevadm", QStringList() << "info" << devicePath); proc.waitForFinished(-1); outPut = proc.readAllStandardOutput(); - if (!outPut.isEmpty()) { - auto idModel = outPut.split("=", QString::SkipEmptyParts); - if (idModel.count() > 1) - model = idModel.at(1).trimmed(); + QString key = "ID_MODEL="; + int start = outPut.indexOf(key); + if (start != -1) { + start += key.length(); // 移动到等号后面 + int end = outPut.indexOf('\n', start); // 找到行尾 + if (end == -1) + end = outPut.length(); // 如果是最后一行 + + model = outPut.mid(start, end - start).trimmed(); if (!model.isEmpty()) return; } diff --git a/service/diskoperation/filesystems/xfs.cpp b/service/diskoperation/filesystems/xfs.cpp index 77416cb5..a368815b 100644 --- a/service/diskoperation/filesystems/xfs.cpp +++ b/service/diskoperation/filesystems/xfs.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -47,12 +47,13 @@ FS XFS::getFilesystemSupport() void XFS::setUsedSectors(Partition &partition) { - QString output, error, strmatch, strcmd; + QString output, error; m_blocksSize = m_numOfFreeOrUsedBlocks = m_totalNumOfBlock = -1; - strcmd = QString("xfs_db -r -c 'sb 0' -c 'print blocksize' -c 'print dblocks'" - " -c 'print fdblocks' %1") - .arg(partition.getPath()); - if (Utils::executWithPipeCmd(strcmd, output, error) == 0) { + QStringList args; + args << "-r" << "-c" << "sb 0" << "-c" << "print blocksize" + << "-c" << "print dblocks" << "-c" << "print fdblocks" + << partition.getPath(); + if (Utils::executWithInputOutputCmd("xfs_db", args, nullptr, output, error) == 0) { auto strList = output.split("\n"); foreach (auto &item, strList) { auto value = item.split("=", QString::SkipEmptyParts); diff --git a/service/diskoperation/luksoperator/luksoperator.cpp b/service/diskoperation/luksoperator/luksoperator.cpp index fe071417..03cb382f 100644 --- a/service/diskoperation/luksoperator/luksoperator.cpp +++ b/service/diskoperation/luksoperator/luksoperator.cpp @@ -1,5 +1,4 @@ -// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -476,20 +475,13 @@ bool LUKSOperator::isLUKS(QString devPath) bool LUKSOperator::format(const LUKS_INFO &luks) { - QProcess proc; - QStringList options; - options << "-c" << QString("echo -n '%1' | cryptsetup --cipher %2 --key-size 256 --hash sha256 luksFormat --label=%3 %4 -q") - .arg(luks.m_decryptStr) - .arg(Utils::getCipherStr(luks.m_crypt)) - .arg(luks.m_fileSystemLabel) - .arg(luks.m_devicePath); - proc.start("/bin/bash", options); - proc.waitForFinished(-1); - proc.waitForReadyRead(); - QString outPut = proc.readAllStandardOutput(); - QString error = proc.errorString(); - proc.close(); - bool success = (proc.exitCode() == 0); + QString outPut, error; + QStringList args; + args << "--cipher" << Utils::getCipherStr(luks.m_crypt) + << "--key-size" << "256" << "--hash" << "sha256" + << "luksFormat" << QString("--label=%1").arg(luks.m_fileSystemLabel) + << luks.m_devicePath << "-q"; + bool success = (Utils::executWithInputOutputCmd("cryptsetup", args, &luks.m_decryptStr, outPut, error) == 0); if (!success) { qCritical() << Q_FUNC_INFO << "output:" << outPut << "\terror:" << error; } @@ -498,32 +490,18 @@ bool LUKSOperator::format(const LUKS_INFO &luks) bool LUKSOperator::open(const LUKS_INFO &luks) { - QProcess proc; - QStringList options; - options << "-c" << QString("echo -n '%1' | cryptsetup open %2 %3 -q") - .arg(luks.m_decryptStr) - .arg(luks.m_devicePath) - .arg(luks.m_mapper.m_dmName); - proc.start("/bin/bash", options); - proc.waitForFinished(-1); - proc.waitForReadyRead();// - proc.close(); - return proc.exitCode() == 0; + QString outPut, error; + QStringList args; + args << "open" << luks.m_devicePath << luks.m_mapper.m_dmName << "-q"; + return (Utils::executWithInputOutputCmd("cryptsetup", args, &luks.m_decryptStr, outPut, error) == 0); } bool LUKSOperator::testKey(const LUKS_INFO &luks) { - QProcess proc; - QStringList options; - options << "-c" << QString("echo -n '%1' | cryptsetup open --test-passphrase %2 %3 -q") - .arg(luks.m_decryptStr) - .arg(luks.m_devicePath) - .arg(luks.m_mapper.m_dmName); - proc.start("/bin/bash", options); - proc.waitForFinished(-1); - proc.waitForReadyRead();// - proc.close(); - return proc.exitCode() == 0; + QString outPut, error; + QStringList args; + args << "open" << "--test-passphrase" << luks.m_devicePath << luks.m_mapper.m_dmName << "-q"; + return (Utils::executWithInputOutputCmd("cryptsetup", args, &luks.m_decryptStr, outPut, error) == 0); } bool LUKSOperator::close(const LUKS_INFO &luks) @@ -597,17 +575,10 @@ bool LUKSOperator::addKeyFile(const LUKS_INFO &luks) } //添加key - QProcess proc; - QStringList options; - options << "-c" << QString("echo -n '%1' | cryptsetup luksAddKey %2 %3 -q") - .arg(luks.m_decryptStr) - .arg(luks.m_devicePath) - .arg(filePath); - proc.start("/bin/bash", options); - proc.waitForFinished(); - proc.waitForReadyRead();// - proc.close(); - return proc.exitCode() == 0; + QString outPut, error; + QStringList args; + args << "luksAddKey" << luks.m_devicePath << filePath << "-q"; + return (Utils::executWithInputOutputCmd("cryptsetup", args, &luks.m_decryptStr, outPut, error) == 0); } bool LUKSOperator::deleteKeyFile(const LUKS_INFO &luks) diff --git a/service/diskoperation/partedcore.cpp b/service/diskoperation/partedcore.cpp index 41274d36..87be2789 100644 --- a/service/diskoperation/partedcore.cpp +++ b/service/diskoperation/partedcore.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -432,8 +432,10 @@ bool PartedCore::detectionPartitionTableError(const QString &devicePath) bool needRewrite = gptIsExpanded(devicePath); if (needRewrite) { QString outPutFix, errorFix; - QString cmdFix = QString("echo w | fdisk %1").arg(devicePath); - Utils::executWithPipeCmd(cmdFix, outPutFix, errorFix); + QStringList args; + args << devicePath; + QString inPut("w\n"); + Utils::executWithInputOutputCmd("fdisk", args, &inPut, outPutFix, errorFix); qDebug() << __FUNCTION__ << "createPartition Partition Table Rewrite Done"; return false; } @@ -3335,8 +3337,10 @@ void PartedCore::reWritePartition(const QString &devicePath) bool needRewrite = gptIsExpanded(devicePath); if (needRewrite) { QString outPutFix, errorFix; - QString cmdFix = QString("echo w | fdisk %1").arg(devicePath); - Utils::executWithPipeCmd(cmdFix, outPutFix, errorFix); + QStringList args; + args << devicePath; + QString inPut("w\n"); + Utils::executWithInputOutputCmd("fdisk", args, &inPut, outPutFix, errorFix); qDebug() << __FUNCTION__ << "createPartition Partition Table Rewrite Done"; return; } diff --git a/service/watcher.cpp b/service/watcher.cpp index d66519aa..969decb5 100644 --- a/service/watcher.cpp +++ b/service/watcher.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -11,24 +11,36 @@ #include #include #include +#include #include namespace DiskManager { /** - * @brief 执行外部命令 - * @param strCmd:外部命令字符串 - * @param outPut:命令控制台输出 - * @param error:错误信息 - * @return exitcode:退出码 + * @brief 检测前端进程 deepin-diskmanager 是否在运行 + * + * 仅启动 ps 一个子进程并在代码内完成过滤,避免使用 shell 解释器,也不再串联 awk/grep 子进程。 + * 等价于管道 `ps -eo cmd | grep -w deepin-diskmanager$`。 + * */ -void Watcher::executCmd(const QString &strCmd, QString &outPut, QString &error) +bool Watcher::isFrontEndRunning(QString &error) { QProcess proc; - proc.start("bash", QStringList() << "-c" << strCmd); + proc.start("ps", QStringList() << "-eo" << "cmd"); proc.waitForFinished(-1); - outPut = proc.readAllStandardOutput(); + error = proc.readAllStandardError(); + + static const QRegularExpression rxMatch("(?:^|[^\\w])deepin-diskmanager$"); + const QStringList lines = QString::fromLocal8Bit(proc.readAllStandardOutput()).split('\n'); + for (const QString &line : lines) { + const QString exe = line.trimmed().section(' ', 0, 0, QString::SectionSkipEmpty); + if (rxMatch.match(exe).hasMatch()) { + return true; + } + } + + return false; } void Watcher::exit() @@ -41,18 +53,12 @@ void Watcher::exit() void Watcher::run() { bool isrun = false; - QString cmd, outPut, error; - //先判断后台服务进程是否存在,如果存在可能是强制退出导致,应先退出后台程序再重新启动磁盘管理器 - cmd = QString("ps -eo pid,cmd |awk '{print $2}' |grep -w deepin-diskmanager$"); + QString error; while (!stoped) { QThread::msleep(500); //0.5 second - executCmd(cmd, outPut, error); - int ret = 0; - ret = outPut.length(); - if (ret) { + if (isFrontEndRunning(error)) { //这里表示前端在运行当中 - // qDebug() << "Set to true!!!!!"; isrun = true; } else { //这里表示,前端启动过,但是现在已经关闭了 @@ -61,7 +67,6 @@ void Watcher::run() _exit(0); } } - // qDebug() << "Sleep !!! == " << ret << " " << outPut << " " << outPut.length() << " "<< error; } } diff --git a/service/watcher.h b/service/watcher.h index ca9bbd2c..26c65bcb 100644 --- a/service/watcher.h +++ b/service/watcher.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-only @@ -24,7 +24,7 @@ class Watcher :public QThread */ void run(); - void executCmd(const QString &strCmd, QString &outPut, QString &error); + bool isFrontEndRunning(QString &error); public Q_SLOTS: void exit();