我想在用戶界面上按下關閉按鈕時關閉嵌入式Linux。我知道我可以用電話做它01:如何在不調用「system()」的情況下使用C++或Qt關閉Linux?
system("shutdown -P now");
編號:Link
但我們知道,使用system
不建議,I'ld想知道如果在C++做的另一種方式這個(如果還有一個使用Qt的特定方法,我也想知道它,儘管一般的C++方法更重要)。
我想在用戶界面上按下關閉按鈕時關閉嵌入式Linux。我知道我可以用電話做它01:如何在不調用「system()」的情況下使用C++或Qt關閉Linux?
system("shutdown -P now");
編號:Link
但我們知道,使用system
不建議,I'ld想知道如果在C++做的另一種方式這個(如果還有一個使用Qt的特定方法,我也想知道它,儘管一般的C++方法更重要)。
在Linux上,您可以調用reboot系統調用來關閉,暫停或重新啓動。 下面的代碼片段展示瞭如何執行poweroff到一臺機器,但要注意,它當然只在Linux上工作:
#include <unistd.h>
#include <linux/reboot.h>
int main() {
reboot(LINUX_REBOOT_MAGIC1,
LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_POWER_OFF, 0);
}
當然,你需要足夠的權限來使用這個系統調用。
這是dbus的用途,雖然因爲它是一個嵌入式系統,所以我不知道是否使用了dbus,它可能是。 – 2015-03-02 14:55:41
@iharob事實上,如果安裝它們,您也可以使用DBus與ConsoleKit或UPower進行通信。但我不希望所有嵌入式系統都能讓它們運行。 – tux3 2015-03-02 14:58:16
這是否會像system(reboot)一樣正常運行systemd服務? – 2017-02-01 09:01:31
如果你的問題是,您認爲系統()不是很安全,你可以使用
system("/bin/sh shutdown -P now");
那麼你可以確保你使用正確的關機功能。
據我在系統()上的讀物記得,爲什麼它不被推薦遠遠超出「使用正確的關閉功能」:)但是,謝謝! – Momergil 2015-03-02 16:38:52
Qt的方式是使用QProcess
運行shutdown命令:
QProcess process;
process.startDetached("shutdown -P now");
謝謝!我可能最終會使用這個,因爲我找不到包含'reboot'的頭文件:x(沒有幫助頁面包括'man'告訴\ o /) – Momergil 2015-03-02 17:31:40
呃,這與'system()'幾乎相同 - 特別是,命令由shell解析。然而,接受參數'QStringList'的另一個'QProcess :: startDetached()'避免了一些問題。 – 2018-01-12 10:47:56
下的glibc,你需要:
#include <unistd.h>
#include <linux/reboot.h>
#include <sys/reboot.h>
int main() {
sync();
reboot(LINUX_REBOOT_CMD_POWER_OFF);
}
再次,一如既往,你需要運行具有足夠的特權。
如果您的系統已經systemd,那麼你可以通過d總線使用logind功能。 的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
有人真的在嵌入式系統上使用systemd嗎? * Shudder。* – 2018-01-12 10:44:28
@TobySpeight me。但是我的嵌入式系統足夠運行Ubuntu Server和圖形應用程序,峯值RAM =〜1.5GB,VRAM =〜2GB。 – Orient 2018-01-12 11:58:36
我想我們對「嵌入」有什麼不同的期望,那麼! – 2018-01-12 12:06:01
爲什麼'系統()'不建議? – cmannett85 2015-03-02 14:45:16
閱讀關於[** DBus **](http://dbus.freedesktop.org/doc/dbus-tutorial.html)。順便說一句,我覺得有一個'QDBus' api。 – 2015-03-02 14:46:15
@ cmannett85出於一個非常簡單的原因,如果OP使用Qt,這意味着它將需要GUI應用程序中的root權限,這真是個壞主意。用'system()'調用程序幾乎總是代表一個安全問題。 – 2015-03-02 14:47:10