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 << property << " is "
36                   << std::visit(
37                          // Convert the variant member to a string for printing.
38                          [](auto v) {
39             if constexpr (std::is_same_v<std::remove_cvref_t<decltype(v)>,
40                                          std::vector<std::string>>)
41             {
42                 return std::string{"Array"};
43             }
44             else if constexpr (std::is_same_v<std::remove_cvref_t<decltype(v)>,
45                                               std::string>)
46             {
47                 return v;
48             }
49             else
50             {
51                 return std::to_string(v);
52             }
53                          },
54                          value)
55             << std::endl;
56     }
57 
58     // Try to set the Architecture property (which won't work).
59     try
60     {
61         co_await systemd.set_property(ctx, "Architecture", "arm64");
62     }
63     catch (const std::exception& e)
64     {
65         std::cout << "Caught exception because you cannot set Architecture: "
66                   << e.what() << std::endl;
67     }
68 
69     // Create a match for the NameOwnerChanged signal.
70     namespace rules = sdbusplus::bus::match::rules;
71     auto match = sdbusplus::async::match(ctx, rules::nameOwnerChanged());
72 
73     // Listen for the signal 4 times...
74     for (size_t i = 0; i < 4; ++i)
75     {
76         auto [service, old_name, new_name] =
77             co_await match.next<std::string, std::string, std::string>();
78 
79         if (!new_name.empty())
80         {
81             std::cout << new_name << " owns " << service << std::endl;
82         }
83         else
84         {
85             std::cout << service << " released" << std::endl;
86         }
87     }
88 
89     // We are all done, so shutdown the server.
90     ctx.request_stop();
91 
92     co_return;
93 }
94 
95 int main()
96 {
97     sdbusplus::async::context ctx;
98     ctx.spawn(startup(ctx));
99     ctx.run();
100 
101     return 0;
102 }
103