Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用C++;或Qt而不调用;系统();?_C++_C_Linux_Qt_Shutdown - Fatal编程技术网

C++ 如何使用C++;或Qt而不调用;系统();?

C++ 如何使用C++;或Qt而不调用;系统();?,c++,c,linux,qt,shutdown,C++,C,Linux,Qt,Shutdown,我想在UI上按下关闭按钮时关闭嵌入式Linux。我知道我可以通过调用系统: system("shutdown -P now"); 参考: 但是不知道使用系统< /> >,我想知道C++中还有没有其他方法来做这件事(如果还有一种具体的方式使用QT来做,我也会知道它,虽然一般的C++方法更重要)。 下面的代码片段显示了如何关闭机器,但请注意,它当然只能在Linux上工作: #include <unistd.h> #include <linux/reboot.h> int

我想在UI上按下关闭按钮时关闭嵌入式Linux。我知道我可以通过调用
系统

system("shutdown -P now");
参考:

<>但是不知道使用<代码>系统< /> >,我想知道C++中还有没有其他方法来做这件事(如果还有一种具体的方式使用QT来做,我也会知道它,虽然一般的C++方法更重要)。 下面的代码片段显示了如何关闭机器,但请注意,它当然只能在Linux上工作:

#include <unistd.h>
#include <linux/reboot.h>

int main() {
    reboot(LINUX_REBOOT_MAGIC1, 
           LINUX_REBOOT_MAGIC2, 
           LINUX_REBOOT_CMD_POWER_OFF, 0);
}
#包括
#包括
int main(){
重新启动(LINUX\u重新启动\u MAGIC1,
LINUX\u重新启动\u MAGIC2,
LINUX\u重新启动\u命令\u电源\u关闭,0);
}

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

如果您认为system()不安全,可以使用

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

然后您可以确定您使用的是正确的关机功能。

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

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

在glibc下,您需要:

#include <unistd.h>
#include <linux/reboot.h>
#include <sys/reboot.h>

int main() {
    sync();
    reboot(LINUX_REBOOT_CMD_POWER_OFF);
}
#包括
#包括
#包括
int main(){
sync();
重新启动(LINUX\u reboot\u CMD\u POWER\u OFF);
}
同样,与往常一样,您需要以足够的权限运行

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


为什么不建议使用
system()
?请阅读。顺便说一句,我认为有一个
QDBus
api。@cmannett85原因很简单,如果OP使用Qt,这意味着它需要GUI应用程序中的root权限,这真是个坏主意。使用
system()
调用程序几乎总是代表一个安全问题。@iharob它是一个嵌入式系统。这就是dbus的用途,尽管由于它是一个嵌入式系统,我不知道是否使用了dbus,它可能是。@iharob确实,如果安装了,您也可以使用dbus与ConsoleKit或UPower通信。不过,我不希望所有嵌入式系统都能运行它们。这是否会停止在
system(重新启动)时正确运行systemd服务
是吗?我建议在
重新启动之前打电话给usleep
-ing几秒钟
这个答案中的代码将不起作用:如果您包括
中的正确原型,您将看到
int reboot(int\u howto)
wrapper而不是直接系统调用签名-这就是glibc提供的。要真正使用神奇数字进行呼叫,您必须使用
syscall(2)
。据我在
system()
上的阅读资料所记得的,不建议使用的原因远远不止“使用正确的关机功能”:)但是谢谢!这个命令在我的Ubuntu上不起作用。显示“/bin/sh:0:无法打开关机”。@AlexanderDyagilev,因为它应该是/bin/sh-c谢谢!我可能最终会使用它,因为我找不到包含
reboot
:x的头文件(没有包含
man
的帮助页面告诉我\o/)呃,这与
system()
几乎相同-特别是,命令由shell解析。但是,另一个接受参数的
QStringList
QProcess::startDetached()
,可以避免一些问题。有人真的在嵌入式系统上使用systemd吗?“发抖!”托比斯看着我。但我的嵌入式系统足够强大,可以运行峰值RAM=~1.5GB和VRAM=~2GB的Ubuntu服务器和图形应用程序。我想我们对什么是“嵌入式”有不同的期望@当然可以。对我来说,它只是一台独立的未维护机器。非桌面和非服务器。比如kiosk。@TobySpeight很多arm SOC都足以运行基于systemd的linux,即默认情况下Yocto Poky发行版与之一起运行。
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;
}
[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