#include <stdio.h>
#include <glib.h>
#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
#include "babeltrace-cfg.h"
#include "babeltrace-cfg-cli-args.h"
#include "babeltrace-cfg-cli-args-default.h"
#define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH"
+/* Application's processing graph (weak) */
+static struct bt_graph *the_graph;
+static bool canceled = false;
+
GPtrArray *loaded_plugins;
BT_HIDDEN
int bt_cli_log_level = BT_LOG_NONE;
+static
+void sigint_handler(int signum)
+{
+ if (signum != SIGINT) {
+ return;
+ }
+
+ if (the_graph) {
+ bt_graph_cancel(the_graph);
+ }
+
+ canceled = true;
+}
+
static
void init_static_data(void)
{
static
int cmd_query(struct bt_config *cfg)
{
- int ret;
+ int ret = 0;
struct bt_component_class *comp_cls = NULL;
struct bt_value *results = NULL;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
comp_cls = find_component_class(cfg->cmd_data.query.cfg_component->plugin_name->str,
cfg->cmd_data.query.cfg_component->comp_cls_name->str,
cfg->cmd_data.query.cfg_component->type);
static
int cmd_help(struct bt_config *cfg)
{
- int ret;
+ int ret = 0;
struct bt_plugin *plugin = NULL;
size_t i;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str);
if (!plugin) {
BT_LOGE("Cannot find plugin: plugin-name=\"%s\"",
int ret = 0;
int plugins_count, component_classes_count = 0, i;
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto end;
- }
-
printf("From the following plugin paths:\n\n");
print_value(stdout, cfg->plugin_paths, 2);
printf("\n");
struct bt_component *comp = NULL;
struct cmd_run_ctx *ctx = data;
- BT_LOGI("Port added to a graph's component: port-addr=%p, port-name=\"%s\"",
+ comp = bt_port_get_component(port);
+ BT_LOGI("Port added to a graph's component: comp-addr=%p, "
+ "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
+ comp, comp ? bt_component_get_name(comp) : "",
port, bt_port_get_name(port));
-
- if (bt_port_is_connected(port)) {
- BT_LOGW_STR("Port is already connected.");
+ if (!comp) {
+ BT_LOGW_STR("Port has no component.");
goto end;
}
- comp = bt_port_get_component(port);
- if (!comp) {
- BT_LOGW_STR("Port has no component.");
+ if (bt_port_is_connected(port)) {
+ BT_LOGW_STR("Port is already connected.");
goto end;
}
void graph_ports_connected_listener(struct bt_port *upstream_port,
struct bt_port *downstream_port, void *data)
{
+ struct bt_component *upstream_comp = bt_port_get_component(upstream_port);
+ struct bt_component *downstream_comp = bt_port_get_component(downstream_port);
+
+ assert(upstream_comp);
+ assert(downstream_comp);
BT_LOGI("Graph's component ports connected: "
+ "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
"upstream-port-addr=%p, upstream-port-name=\"%s\", "
+ "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
"downstream-port-addr=%p, downstream-port-name=\"%s\"",
+ upstream_comp, bt_component_get_name(upstream_comp),
upstream_port, bt_port_get_name(upstream_port),
+ downstream_comp, bt_component_get_name(downstream_comp),
downstream_port, bt_port_get_name(downstream_port));
+ bt_put(upstream_comp);
+ bt_put(downstream_comp);
}
static
}
BT_PUT(ctx->graph);
+ the_graph = NULL;
ctx->cfg = NULL;
}
goto error;
}
+ the_graph = ctx->graph;
ret = bt_graph_add_port_added_listener(ctx->graph,
graph_port_added_listener, ctx);
if (ret) {
return ret;
}
+static inline
+const char *bt_graph_status_str(enum bt_graph_status status)
+{
+ switch (status) {
+ case BT_GRAPH_STATUS_CANCELED:
+ return "BT_GRAPH_STATUS_CANCELED";
+ case BT_GRAPH_STATUS_AGAIN:
+ return "BT_GRAPH_STATUS_AGAIN";
+ case BT_GRAPH_STATUS_END:
+ return "BT_GRAPH_STATUS_END";
+ case BT_GRAPH_STATUS_OK:
+ return "BT_GRAPH_STATUS_OK";
+ case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH:
+ return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH";
+ case BT_GRAPH_STATUS_INVALID:
+ return "BT_GRAPH_STATUS_INVALID";
+ case BT_GRAPH_STATUS_NO_SINK:
+ return "BT_GRAPH_STATUS_NO_SINK";
+ case BT_GRAPH_STATUS_ERROR:
+ return "BT_GRAPH_STATUS_ERROR";
+ default:
+ return "(unknown)";
+ }
+}
+
static
int cmd_run(struct bt_config *cfg)
{
int ret = 0;
struct cmd_run_ctx ctx = { 0 };
- ret = load_all_plugins(cfg->plugin_paths);
- if (ret) {
- goto error;
- }
-
/* Initialize the command's context and the graph object */
if (cmd_run_ctx_init(&ctx, cfg)) {
BT_LOGE_STR("Cannot initialize the command's context.");
goto error;
}
+ if (canceled) {
+ goto end;
+ }
+
BT_LOGI_STR("Running the graph.");
/* Run the graph */
while (true) {
enum bt_graph_status graph_status = bt_graph_run(ctx.graph);
+ BT_LOGV("bt_graph_run() returned: status=%s",
+ bt_graph_status_str(graph_status));
+
switch (graph_status) {
case BT_GRAPH_STATUS_OK:
break;
+ case BT_GRAPH_STATUS_CANCELED:
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
case BT_GRAPH_STATUS_AGAIN:
+ if (bt_graph_is_canceled(ctx.graph)) {
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
+ }
+
if (cfg->cmd_data.run.retry_duration_us > 0) {
BT_LOGV("Got BT_GRAPH_STATUS_AGAIN: sleeping: "
"time-us=%" PRIu64,
cfg->cmd_data.run.retry_duration_us);
if (usleep(cfg->cmd_data.run.retry_duration_us)) {
- // TODO: check EINTR and signal handler
+ if (bt_graph_is_canceled(ctx.graph)) {
+ BT_LOGI_STR("Graph was canceled by user.");
+ goto error;
+ }
}
}
break;
bt_cli_log_level = log_level;
}
+void set_sigint_handler(void)
+{
+ struct sigaction new_action, old_action;
+
+ new_action.sa_handler = sigint_handler;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = 0;
+ sigaction(SIGINT, NULL, &old_action);
+
+ if (old_action.sa_handler != SIG_IGN) {
+ sigaction(SIGINT, &new_action, NULL);
+ }
+}
+
int main(int argc, const char **argv)
{
int ret;
struct bt_config *cfg;
init_log_level();
+ set_sigint_handler();
init_static_data();
cfg = bt_config_cli_args_create_with_default(argc, argv, &retcode);
assert(false);
}
+ BT_LOGI("Command completed: cmd=%d, command-name=\"%s\", ret=%d",
+ cfg->command, cfg->command_name, ret);
warn_command_name_and_directory_clash(cfg);
retcode = ret ? 1 : 0;