Fix: lttng: enable-channel: leak of popt arguments
[lttng-tools.git] / src / common / actions / path.cpp
CommitLineData
27993cc2
JG
1/*
2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc 8#include <lttng/action/path-internal.hpp>
27993cc2 9
f1494934 10namespace {
27993cc2
JG
11struct lttng_action_path_comm {
12 uint32_t index_count;
13 uint64_t indexes[];
14} LTTNG_PACKED;
f1494934 15} /* namespace */
27993cc2
JG
16
17struct lttng_action_path *lttng_action_path_create(
18 const uint64_t *indexes, size_t index_count)
19{
20 int ret;
21 size_t i;
22 struct lttng_action_path *path = NULL;
23
24 if (!indexes && index_count > 0) {
25 goto error;
26 }
27
64803277 28 path = zmalloc<lttng_action_path>();
27993cc2
JG
29 if (!path) {
30 goto error;
31 }
32
33 lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL);
27993cc2
JG
34
35 for (i = 0; i < index_count; i++) {
36 ret = lttng_dynamic_array_add_element(
37 &path->indexes, &indexes[i]);
38 if (ret) {
39 goto error;
40 }
41 }
42
43 goto end;
44error:
45 lttng_action_path_destroy(path);
46 path = NULL;
47end:
48 return path;
49}
50
51enum lttng_action_path_status lttng_action_path_get_index_count(
52 const struct lttng_action_path *path, size_t *index_count)
53{
54 enum lttng_action_path_status status;
55
56 if (!path || !index_count) {
57 status = LTTNG_ACTION_PATH_STATUS_INVALID;
58 goto end;
59 }
60
61 *index_count = lttng_dynamic_array_get_count(&path->indexes);
62 status = LTTNG_ACTION_PATH_STATUS_OK;
63end:
64 return status;
65}
66
67enum lttng_action_path_status lttng_action_path_get_index_at_index(
68 const struct lttng_action_path *path,
69 size_t path_index,
70 uint64_t *out_index)
71{
72 enum lttng_action_path_status status;
73
74 if (!path || !out_index ||
75 path_index >= lttng_dynamic_array_get_count(
76 &path->indexes)) {
77 status = LTTNG_ACTION_PATH_STATUS_INVALID;
78 goto end;
79 }
80
81 *out_index = *((typeof(out_index)) lttng_dynamic_array_get_element(
82 &path->indexes, path_index));
83 status = LTTNG_ACTION_PATH_STATUS_OK;
84end:
85 return status;
86}
87
88void lttng_action_path_destroy(struct lttng_action_path *action_path)
89{
90 if (!action_path) {
91 goto end;
92 }
93
94 lttng_dynamic_array_reset(&action_path->indexes);
95 free(action_path);
96end:
97 return;
98}
99
27993cc2
JG
100int lttng_action_path_copy(const struct lttng_action_path *src,
101 struct lttng_action_path *dst)
102{
103 int ret;
104 size_t i, src_count;
105
a0377dfe
FD
106 LTTNG_ASSERT(src);
107 LTTNG_ASSERT(dst);
27993cc2
JG
108
109 lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL);
110 src_count = lttng_dynamic_array_get_count(&src->indexes);
111
27993cc2
JG
112 for (i = 0; i < src_count; i++) {
113 const void *index = lttng_dynamic_array_get_element(
114 &src->indexes, i);
115
116 ret = lttng_dynamic_array_add_element(&dst->indexes, index);
117 if (ret) {
118 goto error;
119 }
120 }
121
122 ret = 0;
123 goto end;
124error:
125 lttng_dynamic_array_reset(&dst->indexes);
126end:
127 return ret;
128}
129
27993cc2
JG
130ssize_t lttng_action_path_create_from_payload(
131 struct lttng_payload_view *view,
132 struct lttng_action_path **_action_path)
133{
134 ssize_t consumed_size = 0, ret = -1;
135 const struct lttng_action_path_comm *header;
136 struct lttng_action_path *action_path = NULL;
137 const struct lttng_payload_view header_view =
138 lttng_payload_view_from_view(view, 0, sizeof(*header));
139
140 if (!lttng_payload_view_is_valid(&header_view)) {
141 goto end;
142 }
143
144 header = (typeof(header)) header_view.buffer.data;
145 consumed_size += header_view.buffer.size;
7afaf43b
JR
146
147 /*
148 * An action path of size 0 can exist and represents a trigger with a
149 * single non-list action. Handle it differently since a payload view of
150 * size 0 is considered invalid.
151 */
152 if (header->index_count != 0)
27993cc2
JG
153 {
154 const struct lttng_payload_view indexes_view =
155 lttng_payload_view_from_view(view,
156 consumed_size,
157 header->index_count *
158 sizeof(uint64_t));
159
160 if (!lttng_payload_view_is_valid(&indexes_view)) {
161 goto end;
162 }
163
164 consumed_size += indexes_view.buffer.size;
165 action_path = lttng_action_path_create(
166 (const uint64_t *) indexes_view.buffer.data,
167 header->index_count);
168 if (!action_path) {
169 goto end;
170 }
7afaf43b
JR
171 } else {
172 action_path = lttng_action_path_create(NULL, 0);
173 if (!action_path) {
174 goto end;
175 }
27993cc2
JG
176 }
177
178 ret = consumed_size;
cb9222ff 179 *_action_path = action_path;
27993cc2
JG
180end:
181 return ret;
182}
183
27993cc2
JG
184int lttng_action_path_serialize(const struct lttng_action_path *action_path,
185 struct lttng_payload *payload)
186{
187 int ret;
188 size_t index_count, i;
189 enum lttng_action_path_status status;
a6bc4ca9 190 lttng_action_path_comm comm;
27993cc2
JG
191
192 status = lttng_action_path_get_index_count(action_path, &index_count);
193 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
194 ret = -1;
195 goto end;
196 }
197
a6bc4ca9
SM
198 comm = {
199 .index_count = (uint32_t) index_count,
200 };
27993cc2 201 ret = lttng_dynamic_buffer_append(&payload->buffer,
a6bc4ca9 202 &comm,
27993cc2
JG
203 sizeof(struct lttng_action_path_comm));
204
205 for (i = 0; i < index_count; i++) {
206 uint64_t path_index;
207
208 status = lttng_action_path_get_index_at_index(
209 action_path, i, &path_index);
210 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
211 ret = -1;
212 goto end;
213 }
214
215 ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index,
216 sizeof(path_index));
217 if (ret) {
218 goto end;
219 }
220 }
221
222 ret = 0;
223end:
224 return ret;
225}
This page took 0.041573 seconds and 4 git commands to generate.