1 #include <sdbusplus/async.hpp> 2 3 #include <iostream> 4 #include <string> 5 #include <variant> 6 #include <vector> 7 8 auto startup(sdbusplus::async::context& ctx) -> sdbusplus::async::task<> 9 { 10 // Create a proxy to the systemd manager object. 11 constexpr auto systemd = sdbusplus::async::proxy() 12 .service("org.freedesktop.systemd1") 13 .path("/org/freedesktop/systemd1") 14 .interface("org.freedesktop.systemd1.Manager"); 15 16 // Call ListUnitFiles method. 17 using ret_type = std::vector<std::tuple<std::string, std::string>>; 18 for (auto& [file, status] : 19 co_await systemd.call<ret_type>(ctx, "ListUnitFiles")) 20 { 21 std::cout << file << " " << status << std::endl; 22 } 23 24 // Get the Architecture property. 25 std::cout << co_await systemd.get_property<std::string>(ctx, "Architecture") 26 << std::endl; 27 28 // Get all the properties. 29 using variant_type = 30 std::variant<bool, std::string, std::vector<std::string>, uint64_t, 31 int32_t, uint32_t, double>; 32 for (auto& [property, value] : 33 co_await systemd.get_all_properties<variant_type>(ctx)) 34 { 35 std::cout 36 << property << " is " 37 << std::visit( 38 // Convert the variant member to a string for printing. 39 [](auto v) { 40 if constexpr (std::is_same_v< 41 std::remove_cvref_t<decltype(v)>, 42 std::vector<std::string>>) 43 { 44 return std::string{"Array"}; 45 } 46 else if constexpr (std::is_same_v< 47 std::remove_cvref_t<decltype(v)>, 48 std::string>) 49 { 50 return v; 51 } 52 else 53 { 54 return std::to_string(v); 55 } 56 }, 57 value) 58 << std::endl; 59 } 60 61 // Try to set the Architecture property (which won't work). 62 try 63 { 64 co_await systemd.set_property(ctx, "Architecture", "arm64"); 65 } 66 catch (const std::exception& e) 67 { 68 std::cout << "Caught exception because you cannot set Architecture: " 69 << e.what() << std::endl; 70 } 71 72 // Create a match for the NameOwnerChanged signal. 73 namespace rules = sdbusplus::bus::match::rules; 74 auto match = sdbusplus::async::match(ctx, rules::nameOwnerChanged()); 75 76 // Listen for the signal 4 times... 77 for (size_t i = 0; i < 4; ++i) 78 { 79 auto [service, old_name, new_name] = 80 co_await match.next<std::string, std::string, std::string>(); 81 82 if (!new_name.empty()) 83 { 84 std::cout << new_name << " owns " << service << std::endl; 85 } 86 else 87 { 88 std::cout << service << " released" << std::endl; 89 } 90 } 91 92 // We are all done, so shutdown the server. 93 ctx.request_stop(); 94 95 co_return; 96 } 97 98 int main() 99 { 100 sdbusplus::async::context ctx; 101 ctx.spawn(startup(ctx)); 102 ctx.run(); 103 104 return 0; 105 } 106