-
Notifications
You must be signed in to change notification settings - Fork 25
/
utils.hpp
120 lines (102 loc) · 3.33 KB
/
utils.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "config.h"
#include <sdbusplus/server.hpp>
#include <fstream>
#include <map>
#include <string>
namespace utils
{
using PropertyValue = std::variant<std::string>;
/**
* @brief Get the bus service
*
* @return the bus service as a string
**/
std::string getService(sdbusplus::bus_t& bus, const std::string& path,
const std::string& interface);
/** @brief Get property(type: variant)
*
* @param[in] bus - bus handler
* @param[in] objectPath - D-Bus object path
* @param[in] interface - D-Bus interface
* @param[in] propertyName - D-Bus property name
*
* @return The value of the property(type: variant)
*
* @throw sdbusplus::exception_t when it fails
*/
template <typename T>
T getProperty(sdbusplus::bus_t& bus, const std::string& objectPath,
const std::string& interface, const std::string& propertyName)
{
std::variant<T> value{};
auto service = getService(bus, objectPath, interface);
if (service.empty())
{
return std::get<T>(value);
}
auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
"org.freedesktop.DBus.Properties", "Get");
method.append(interface, propertyName);
auto reply = bus.call(method);
reply.read(value);
return std::get<T>(value);
}
/** @brief Set D-Bus property
*
* @param[in] bus - bus handler
* @param[in] objectPath - D-Bus object path
* @param[in] interface - D-Bus interface
* @param[in] propertyName - D-Bus property name
* @param[in] value - The value to be set
*
* @throw sdbusplus::exception_t when it fails
*/
void setProperty(sdbusplus::bus_t& bus, const std::string& objectPath,
const std::string& interface, const std::string& propertyName,
const PropertyValue& value);
/**
* @brief Merge more files
*
* @param[in] srcFiles - source files
* @param[out] dstFile - destination file
* @return
**/
void mergeFiles(const std::vector<std::string>& srcFiles,
const std::string& dstFile);
namespace internal
{
/**
* @brief Construct an argument vector to be used with an exec command, which
* requires the name of the executable to be the first argument, and a
* null terminator to be the last.
* @param[in] name - Name of the executable
* @param[in] args - Optional arguments
* @return char* vector
*/
template <typename... Arg>
constexpr auto constructArgv(const char* name, Arg&&... args)
{
std::vector<char*> argV{
{const_cast<char*>(name), const_cast<char*>(args)..., nullptr}};
return argV;
}
/**
* @brief Helper function to execute command in child process
* @param[in] args - Executable plus optional arguments
* @return 0 and command output on success
*/
std::pair<int, std::string> executeCmd(char** args);
} // namespace internal
/**
* @brief Execute command in child process
* @param[in] path - Fully qualified name of the executable to run
* @param[in] args - Optional arguments
* @return 0 and command output on success
*/
template <typename... Arg>
std::pair<int, std::string> execute(const char* path, Arg&&... args)
{
auto argArray = internal::constructArgv(path, std::forward<Arg>(args)...);
return internal::executeCmd(argArray.data());
}
} // namespace utils