C++ 如何使用C++;或Qt而不调用;系统();?
我想在UI上按下关闭按钮时关闭嵌入式Linux。我知道我可以通过调用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
系统:
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