📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| 102行目: | 102行目: | ||
D-Bus経由でSystemdと直接通信するため、より柔軟で、プログラム内から制御できるようになっている。<br> | D-Bus経由でSystemdと直接通信するため、より柔軟で、プログラム内から制御できるようになっている。<br> | ||
<br> | <br> | ||
ただし、サンプルコードを実行するには、適切な権限が必要となる。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
#include <iostream> | |||
#include <string> | |||
#include <sdbus-c++/sdbus-c++.h> | #include <sdbus-c++/sdbus-c++.h> | ||
#include < | // #include <atomic> | ||
// std::atomic<bool> g_shouldExit(false); | |||
// UnitStateChangedシグナルハンドラ | |||
// ただし、Systemdサービスはシグナルを送信しないため、今回は設定しない | |||
// void onUnitStateChanged(sdbus::Signal signal) | |||
// { | |||
// std::string unitName, newState, oldState; | |||
// signal >> unitName >> newState >> oldState; | |||
// std::cout << "Unit " << unitName << " changed state from " << oldState << " to " << newState << std::endl; | |||
// if (unitName == "smb.service" && (newState == "active" || newState == "failed")) { | |||
// g_shouldExit.store(true); | |||
// } | |||
// } | |||
// smb.serviceが正常に開始されているかどうかを確認する | |||
bool checkServiceStatus(sdbus::IProxy &systemdProxy, sdbus::InterfaceName &interfaceName, const std::string &serviceName) | |||
{ | |||
try { | |||
// smb.serviceのユニットパスを取得する | |||
sdbus::MethodName methodName{"GetUnit"}; | |||
auto method = systemdProxy.createMethodCall(interfaceName, methodName); | |||
method << serviceName; | |||
auto reply = systemdProxy.callMethod(method); | |||
sdbus::ObjectPath unitPath; | |||
reply >> unitPath; | |||
// 取得したsmb.serviceのユニットパスを使用して、smb.serviceの開始状態を取得 | |||
auto unitProxy = sdbus::createProxy(systemdProxy.getConnection(), std::move(sdbus::ServiceName{"org.freedesktop.systemd1"}), unitPath); | |||
auto getProperty = unitProxy->createMethodCall(sdbus::InterfaceName{"org.freedesktop.DBus.Properties"}, sdbus::MethodName{"Get"}); | |||
getProperty << "org.freedesktop.systemd1.Unit" << "ActiveState"; | |||
auto propertyReply = unitProxy->callMethod(getProperty); | |||
sdbus::Variant variant; | |||
propertyReply >> variant; | |||
std::string state = variant.get<std::string>(); | |||
return (state == "active"); | |||
} | |||
catch (const sdbus::Error &e) { | |||
// sdbus::Errorをキャッチしてエラーメッセージを表示 | |||
std::cerr << "Error checking service status: " << e.getName() << " - " << e.getMessage() << std::endl; | |||
return false; | |||
} | |||
catch (const std::exception &e) { | |||
// std::exceptionをキャッチして一般エラーを処理 | |||
std::cerr << "Error: " << e.what() << std::endl; | |||
return false; | |||
} | |||
} | |||
int main() | int main(int argc, char *argv[]) | ||
{ | { | ||
// システムバスへの接続を作成 | |||
auto connection = sdbus::createSystemBusConnection(); | |||
// Systemdサービスのマネージャーインターフェースへのプロキシオブジェクトを作成 | |||
sdbus::ServiceName destination("org.freedesktop.systemd1"); | |||
sdbus::ObjectPath objectPath("/org/freedesktop/systemd1"); | |||
auto systemdProxy = sdbus::createProxy(*connection, std::move(destination), std::move(objectPath)); | |||
// D-Busインターフェース名を指定 | |||
sdbus::InterfaceName interfaceName("org.freedesktop.systemd1.Manager"); | |||
// UnitStateChangedシグナルのハンドラを登録 | |||
// ただし、Systemdサービスはシグナルを送信しないため、今回は設定しない | |||
//sdbus::SignalName signalName("UnitStateChanged"); | |||
//systemdProxy->registerSignalHandler(interfaceName, signalName, &onUnitStateChanged); | |||
try { | try { | ||
// "StartUnit"はSystemdサービスのメソッド名 | |||
sdbus::MethodName methodName{"StartUnit"}; | |||
auto method = systemdProxy->createMethodCall(interfaceName, methodName); | |||
// "smb.service"は開始するSystemdサービス名 | |||
// "replace"はSystemdサービスの起動モード | |||
method << "smb.service" << "replace"; | |||
auto reply = systemdProxy->callMethod(method); | |||
sdbus::ObjectPath jobPath; | |||
reply >> jobPath; | |||
std::cout << "StartUnit job path: " << jobPath << std::endl; | |||
std::string serviceName = "smb.service"; | |||
if (checkServiceStatus(*systemdProxy, interfaceName, serviceName)) { | |||
std::cout << "Service " << serviceName << " state: " << "avtive" << std::endl; | |||
} | |||
} | } | ||
catch (const sdbus::Error &e) { | catch (const sdbus::Error &e) { | ||
// sdbus::Errorをキャッチしてエラーメッセージを表示 | // sdbus::Errorをキャッチしてエラーメッセージを表示 | ||
std::cerr << " | std::cerr << "Error starting smb.service: " << e.getName() << " - " << e.getMessage() << std::endl; | ||
return -1; | return -1; | ||
} | } | ||
| 145行目: | 214行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== 使用例 : ユーザ定義のD-Busサービスの実行 ==== | ==== 使用例 : ユーザ定義のD-Busサービスの実行 ==== | ||
===== D-Busサービス ===== | ===== D-Busサービス ===== | ||