如何在不调用"system()"的情况下使用 C++ 或 Qt 关闭 Linux?

How to shutdown Linux using C++ or Qt without call to "system()"?

本文关键字:C++ Qt Linux 关闭 情况下 调用 system      更新时间:2023-10-16

当按下UI上的关闭按钮时,我想关闭嵌入式Linux。我知道我可以打电话给system:

system("shutdown -P now");

参考:链接

但是知道不建议使用system,我想知道C++中是否有其他方法可以做到这一点(如果使用Qt也有特定的方法可以做到,我也想知道,尽管通用C++方法更重要)。

在Linux上,您可以调用重新启动系统调用来关闭电源、停止或重新启动。以下片段显示了如何关闭机器的电源,但请注意,它当然只能在Linux上工作:

#include <unistd.h>
#include <linux/reboot.h>
int main() {
    reboot(LINUX_REBOOT_MAGIC1, 
           LINUX_REBOOT_MAGIC2, 
           LINUX_REBOOT_CMD_POWER_OFF, 0);
}

当然,您需要足够的权限才能使用此系统调用。

在glibc下,您需要:

#include <unistd.h>
#include <linux/reboot.h>
#include <sys/reboot.h>
int main() {
    sync();
    reboot(LINUX_REBOOT_CMD_POWER_OFF);
}

同样,和往常一样,您需要以足够的权限运行。

重新启动的手册页

如果您的系统有systemd,那么您可以通过D-Bus使用login功能Qt解决方案如下(刚刚测试):

QDBusInterface logind{"org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus()};
const auto message = logind.callWithArgumentList(QDBus::Block, "CanPowerOff", {});
QDBusPendingReply< QString > canPowerOff = message;
Q_ASSERT(canPowerOff.isFinished());
if (canPowerOff.isError()) {
    const auto error = canPowerOff.error();
    qWarning().noquote()
            << QDBusInterface::tr("Asynchronous call finished with error: %1 (%2)")
               .arg(error.name(), error.message());
    return EXIT_FAILURE;
}
if (canPowerOff.value() == "yes") {
    QDBusPendingReply<> powerOff = logind.callWithArgumentList(QDBus::Block, "PowerOff", {true, });
    Q_ASSERT(powerOff.isFinished());
    if (powerOff.isError()) {
        const auto error = powerOff.error();
        qWarning().noquote()
                << QDBusInterface::tr("Asynchronous call finished with error: %1 (%2)")
                   .arg(error.name(), error.message());
        return EXIT_FAILURE;
    }
} else {
    qCritical().noquote()
            << QCoreApplication::translate("poweroff", "Can't power off: CanPowerOff() result is %1")
               .arg(canPowerOff.value());
    return EXIT_FAILURE;
}

也可能需要添加一个文件/etc/polkit-1/localauthority/50-local.d/10-enable-shutdown.pkla来抑制交互式身份验证要求:

[Enable shoutdown for users]
Identity=unix-group:users
Action=org.freedesktop.login1;org.freedesktop.login1.power-off;org.freedesktop.login1.power-off-ignore-inhibit;org.freedesktop.login1.power-off-multiple-sessions
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Qt方法是使用QProcess运行关闭命令:

QProcess process;
process.startDetached("shutdown -P now");

如果你的问题是你认为系统()不安全,你可以使用

system("/bin/sh shutdown -P now");

那么你可以确定你使用的是正确的关机功能。