#define _LGPL_SOURCE
#include <common/compat/getenv.hpp>
#include <common/compat/string.hpp>
+#include <common/make-unique-wrapper.hpp>
#include <common/sessiond-comm/sessiond-comm.hpp>
#include <common/string-utils/string-utils.hpp>
#include <common/utils.hpp>
#define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
#endif
-static int opt_event_type;
-static const char *opt_loglevel;
-static int opt_loglevel_type;
-static int opt_kernel;
-static char *opt_session_name;
-static int opt_userspace;
-static int opt_jul;
-static int opt_log4j;
-static int opt_python;
-static int opt_enable_all;
-static char *opt_probe;
-static char *opt_userspace_probe;
-static char *opt_function;
-static char *opt_channel_name;
-static char *opt_filter;
-static char *opt_exclude;
+namespace {
+void _mi_lttng_writer_deleter_func(mi_writer *writer)
+{
+ if (writer && mi_lttng_writer_destroy(writer)) {
+ LTTNG_THROW_ERROR("Failed to destroy mi_writer instance");
+ }
+}
+
+using mi_writer_uptr = std::unique_ptr<
+ mi_writer,
+ lttng::memory::create_deleter_class<mi_writer, _mi_lttng_writer_deleter_func>::deleter>;
+
+int opt_event_type;
+const char *opt_loglevel;
+int opt_loglevel_type;
+int opt_kernel;
+char *opt_session_name;
+int opt_userspace;
+int opt_jul;
+int opt_log4j;
+int opt_python;
+int opt_enable_all;
+char *opt_probe;
+char *opt_userspace_probe;
+char *opt_function;
+char *opt_channel_name;
+char *opt_filter;
+char *opt_exclude;
+
+struct lttng_handle *handle;
+mi_writer_uptr writer;
#ifdef LTTNG_EMBED_HELP
static const char help_msg[] =
OPT_EXCLUDE,
};
-static struct lttng_handle *handle;
-static struct mi_writer *writer;
-
-static struct poptOption long_options[] = {
+struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
{ "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr },
{ "session", 's', POPT_ARG_STRING, &opt_session_name, 0, nullptr, nullptr },
/*
* Parse probe options.
*/
-static int parse_probe_opts(struct lttng_event *ev, char *opt)
+int parse_probe_opts(struct lttng_event *ev, char *opt)
{
int ret = CMD_SUCCESS;
int match;
return ret;
}
-static const char *print_channel_name(const char *name)
+const char *print_channel_name(const char *name)
{
return name ?: DEFAULT_CHANNEL_NAME;
}
-static const char *print_raw_channel_name(const char *name)
+const char *print_raw_channel_name(const char *name)
{
return name ?: "<default>";
}
/*
* Mi print exlcusion list
*/
-static int mi_print_exclusion(const struct lttng_dynamic_pointer_array *exclusions)
+int mi_print_exclusion(const struct lttng_dynamic_pointer_array *exclusions)
{
int ret;
size_t i;
goto end;
}
- ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
+ ret = mi_lttng_writer_open_element(writer.get(), config_element_exclusions);
if (ret) {
goto end;
}
(const char *) lttng_dynamic_pointer_array_get_pointer(exclusions, i);
ret = mi_lttng_writer_write_element_string(
- writer, config_element_exclusion, exclusion);
+ writer.get(), config_element_exclusion, exclusion);
if (ret) {
goto end;
}
}
/* Close exclusions element */
- ret = mi_lttng_writer_close_element(writer);
+ ret = mi_lttng_writer_close_element(writer.get());
end:
return ret;
/*
* Return allocated string for pretty-printing exclusion names.
*/
-static char *print_exclusions(const struct lttng_dynamic_pointer_array *exclusions)
+char *print_exclusions(const struct lttng_dynamic_pointer_array *exclusions)
{
int length = 0;
size_t i;
return ret;
}
-static int check_exclusion_subsets(const char *event_name, const char *exclusion)
+int check_exclusion_subsets(const char *event_name, const char *exclusion)
{
bool warn = false;
int ret = 0;
return ret;
}
-int validate_exclusion_list(const char *event_name,
- const struct lttng_dynamic_pointer_array *exclusions)
-{
- int ret;
-
- /* Event name must be a valid globbing pattern to allow exclusions. */
- if (!strutils_is_star_glob_pattern(event_name)) {
- ERR("Event %s: Exclusions can only be used with a globbing pattern", event_name);
- goto error;
- }
-
- /*
- * If the event name is a star-at-end only globbing pattern,
- * then we can validate the individual exclusions. Otherwise
- * all exclusions are passed to the session daemon.
- */
- if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
- size_t i, num_exclusions;
-
- num_exclusions = lttng_dynamic_pointer_array_get_count(exclusions);
-
- for (i = 0; i < num_exclusions; i++) {
- const char *exclusion =
- (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions,
- i);
-
- if (!strutils_is_star_glob_pattern(exclusion) ||
- strutils_is_star_at_the_end_only_glob_pattern(exclusion)) {
- ret = check_exclusion_subsets(event_name, exclusion);
- if (ret) {
- goto error;
- }
- }
- }
- }
-
- ret = 0;
- goto end;
-
-error:
- ret = -1;
-
-end:
- return ret;
-}
-
-static int create_exclusion_list_and_validate(const char *event_name,
- const char *exclusions_arg,
- struct lttng_dynamic_pointer_array *exclusions)
+int create_exclusion_list_and_validate(const char *event_name,
+ const char *exclusions_arg,
+ struct lttng_dynamic_pointer_array *exclusions)
{
int ret = 0;
return ret;
}
-static void warn_on_truncated_exclusion_names(const struct lttng_dynamic_pointer_array *exclusions,
- int *warn)
+void warn_on_truncated_exclusion_names(const struct lttng_dynamic_pointer_array *exclusions,
+ int *warn)
{
size_t i;
const size_t num_exclusions = lttng_dynamic_pointer_array_get_count(exclusions);
* Enabling event using the lttng API.
* Note: in case of error only the last error code will be return.
*/
-static int enable_events(char *session_name, char *event_list)
+int enable_events(char *session_name, char *event_list)
{
int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1;
/* Prepare Mi */
if (lttng_opt_mi) {
/* Open a events element */
- ret = mi_lttng_writer_open_element(writer, config_element_events);
+ ret = mi_lttng_writer_open_element(writer.get(), config_element_events);
if (ret) {
ret = CMD_ERROR;
goto error;
ev->enabled = 0;
success = 0;
}
- ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
+ ret = mi_lttng_event(writer.get(), ev, 1, handle->domain.type);
if (ret) {
ret = CMD_ERROR;
goto error;
/* Success ? */
ret = mi_lttng_writer_write_element_bool(
- writer, mi_lttng_element_command_success, success);
+ writer.get(), mi_lttng_element_command_success, success);
if (ret) {
ret = CMD_ERROR;
goto error;
}
/* Close event element */
- ret = mi_lttng_writer_close_element(writer);
+ ret = mi_lttng_writer_close_element(writer.get());
if (ret) {
ret = CMD_ERROR;
goto error;
ev->enabled = 1;
}
- ret = mi_lttng_event(writer, ev, 1, handle->domain.type);
+ ret = mi_lttng_event(writer.get(), ev, 1, handle->domain.type);
if (ret) {
ret = CMD_ERROR;
goto error;
/* Success ? */
ret = mi_lttng_writer_write_element_bool(
- writer, mi_lttng_element_command_success, success);
+ writer.get(), mi_lttng_element_command_success, success);
if (ret) {
ret = CMD_ERROR;
goto end;
}
/* Close event element */
- ret = mi_lttng_writer_close_element(writer);
+ ret = mi_lttng_writer_close_element(writer.get());
if (ret) {
ret = CMD_ERROR;
goto end;
/* Close Mi */
if (lttng_opt_mi) {
/* Close events element */
- ret = mi_lttng_writer_close_element(writer);
+ ret = mi_lttng_writer_close_element(writer.get());
if (ret) {
ret = CMD_ERROR;
goto error;
return ret;
}
+void _poptContextFree_deleter_func(poptContext ctx)
+{
+ poptFreeContext(ctx);
+}
+
+} /* namespace */
+
+int validate_exclusion_list(const char *event_name,
+ const struct lttng_dynamic_pointer_array *exclusions)
+{
+ int ret;
+
+ /* Event name must be a valid globbing pattern to allow exclusions. */
+ if (!strutils_is_star_glob_pattern(event_name)) {
+ ERR("Event %s: Exclusions can only be used with a globbing pattern", event_name);
+ goto error;
+ }
+
+ /*
+ * If the event name is a star-at-end only globbing pattern,
+ * then we can validate the individual exclusions. Otherwise
+ * all exclusions are passed to the session daemon.
+ */
+ if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) {
+ size_t i, num_exclusions;
+
+ num_exclusions = lttng_dynamic_pointer_array_get_count(exclusions);
+
+ for (i = 0; i < num_exclusions; i++) {
+ const char *exclusion =
+ (const char *) lttng_dynamic_pointer_array_get_pointer(exclusions,
+ i);
+
+ if (!strutils_is_star_glob_pattern(exclusion) ||
+ strutils_is_star_at_the_end_only_glob_pattern(exclusion)) {
+ ret = check_exclusion_subsets(event_name, exclusion);
+ if (ret) {
+ goto error;
+ }
+ }
+ }
+ }
+
+ ret = 0;
+ goto end;
+
+error:
+ ret = -1;
+
+end:
+ return ret;
+}
+
/*
* Add event to trace session
*/
int cmd_enable_events(int argc, const char **argv)
{
int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
- static poptContext pc;
char *session_name = nullptr;
char *event_list = nullptr;
const char *arg_event_list = nullptr;
const char *leftover = nullptr;
int event_type = -1;
- pc = poptGetContext(nullptr, argc, argv, long_options, 0);
- poptReadDefaultConfig(pc, 0);
+ auto pc = lttng::make_unique_wrapper<poptContext_s, _poptContextFree_deleter_func>(
+ poptGetContext(nullptr, argc, argv, long_options, 0));
+ poptReadDefaultConfig(pc.get(), 0);
/* Default event type */
opt_event_type = LTTNG_EVENT_ALL;
- while ((opt = poptGetNextOpt(pc)) != -1) {
+ while ((opt = poptGetNextOpt(pc.get())) != -1) {
switch (opt) {
case OPT_HELP:
SHOW_HELP();
break;
case OPT_LOGLEVEL:
opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
- opt_loglevel = poptGetOptArg(pc);
+ opt_loglevel = poptGetOptArg(pc.get());
break;
case OPT_LOGLEVEL_ONLY:
opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
- opt_loglevel = poptGetOptArg(pc);
+ opt_loglevel = poptGetOptArg(pc.get());
break;
case OPT_LIST_OPTIONS:
list_cmd_options(stdout, long_options);
/* Mi check */
if (lttng_opt_mi) {
- writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
+ writer = mi_writer_uptr(mi_lttng_writer_create(fileno(stdout), lttng_opt_mi));
if (!writer) {
ret = -LTTNG_ERR_NOMEM;
goto end;
}
/* Open command element */
- ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_enable_event);
+ ret = mi_lttng_writer_command_open(writer.get(),
+ mi_lttng_element_command_enable_event);
if (ret) {
ret = CMD_ERROR;
goto end;
}
/* Open output element */
- ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
+ ret = mi_lttng_writer_open_element(writer.get(), mi_lttng_element_command_output);
if (ret) {
ret = CMD_ERROR;
goto end;
}
}
- arg_event_list = poptGetArg(pc);
+ arg_event_list = poptGetArg(pc.get());
if (arg_event_list == nullptr && opt_enable_all == 0) {
ERR("Missing event name(s).");
ret = CMD_ERROR;
}
}
- leftover = poptGetArg(pc);
+ leftover = poptGetArg(pc.get());
if (leftover) {
ERR("Unknown argument: %s", leftover);
ret = CMD_ERROR;
/* Mi closing */
if (lttng_opt_mi) {
/* Close output element */
- ret = mi_lttng_writer_close_element(writer);
+ ret = mi_lttng_writer_close_element(writer.get());
if (ret) {
ret = CMD_ERROR;
goto end;
}
ret = mi_lttng_writer_write_element_bool(
- writer, mi_lttng_element_command_success, success);
+ writer.get(), mi_lttng_element_command_success, success);
if (ret) {
ret = CMD_ERROR;
goto end;
}
/* Command element close */
- ret = mi_lttng_writer_command_close(writer);
+ ret = mi_lttng_writer_command_close(writer.get());
if (ret) {
ret = CMD_ERROR;
goto end;
}
end:
- /* Mi clean-up */
- if (writer && mi_lttng_writer_destroy(writer)) {
- /* Preserve original error code */
- ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
- }
-
if (opt_session_name == nullptr) {
free(session_name);
}
/* Overwrite ret if an error occurred in enable_events */
ret = command_ret ? command_ret : ret;
-
- poptFreeContext(pc);
return ret;
}