+ /* Open pids element */
+ ret = mi_lttng_pids_open(writer);
+ if (ret) {
+ goto end;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (cur_pid != fields[i].event.pid) {
+ if (pid_element_open) {
+ if (event_element_open) {
+ /*
+ * Close the previous fields element
+ * and the previous event
+ */
+ ret = mi_lttng_close_multi_element(writer, 2);
+ if (ret) {
+ goto end;
+ }
+ event_element_open = 0;
+ }
+ /* Close the previous events, pid element */
+ ret = mi_lttng_close_multi_element(writer, 2);
+ if (ret) {
+ goto end;
+ }
+ pid_element_open = 0;
+ }
+
+ cur_pid = fields[i].event.pid;
+ cmdline = get_cmdline_by_pid(cur_pid);
+ if (!pid_element_open) {
+ /* Open and write a pid element */
+ ret = mi_lttng_pid(writer, cur_pid, cmdline, 1);
+ if (ret) {
+ goto error;
+ }
+
+ /* Open events element */
+ ret = mi_lttng_events_open(writer);
+ if (ret) {
+ goto error;
+ }
+ pid_element_open = 1;
+ }
+ free(cmdline);
+ /* Wipe current event since we are about to print a new PID. */
+ memset(&cur_event, 0, sizeof(cur_event));
+ }
+
+ if (strcmp(cur_event.name, fields[i].event.name) != 0) {
+ if (event_element_open) {
+ /* Close the previous fields element and the previous event */
+ ret = mi_lttng_close_multi_element(writer, 2);
+ if (ret) {
+ goto end;
+ }
+ event_element_open = 0;
+ }
+
+ memcpy(&cur_event, &fields[i].event,
+ sizeof(cur_event));
+
+ if (!event_element_open) {
+ /* Open and write the event */
+ ret = mi_lttng_event(writer, &cur_event, 1);
+ if (ret) {
+ goto end;
+ }
+
+ /* Open a fields element */
+ ret = mi_lttng_event_fields_open(writer);
+ if (ret) {
+ goto end;
+ }
+ event_element_open = 1;
+ }
+ }
+
+ /* Print the event_field */
+ ret = mi_lttng_event_field(writer, &fields[i]);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ /* Close pids, domain, domains */
+ ret = mi_lttng_close_multi_element(writer, 3);
+end:
+ return ret;
+error:
+ free(cmdline);
+ return ret;
+}
+
+/*
+ * Ask session daemon for all user space tracepoint fields available.
+ */
+static int list_ust_event_fields(void)
+{
+ int i, size, ret = CMD_SUCCESS;
+ struct lttng_domain domain;
+ struct lttng_handle *handle;
+ struct lttng_event_field *event_field_list;
+ pid_t cur_pid = 0;
+ char *cmdline = NULL;
+
+ struct lttng_event cur_event;
+
+ memset(&domain, 0, sizeof(domain));
+ memset(&cur_event, 0, sizeof(cur_event));
+
+ DBG("Getting UST tracing event fields");
+
+ domain.type = LTTNG_DOMAIN_UST;
+
+ handle = lttng_create_handle(NULL, &domain);
+ if (handle == NULL) {
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ size = lttng_list_tracepoint_fields(handle, &event_field_list);
+ if (size < 0) {
+ ERR("Unable to list UST event fields: %s", lttng_strerror(size));
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ if (lttng_opt_mi) {
+ /* Mi print */
+ ret = mi_list_ust_event_fields(event_field_list, size, &domain);
+ if (ret) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+ } else {
+ /* Pretty print */
+ MSG("UST events:\n-------------");
+
+ if (size == 0) {
+ MSG("None");
+ }
+
+ for (i = 0; i < size; i++) {
+ if (cur_pid != event_field_list[i].event.pid) {
+ cur_pid = event_field_list[i].event.pid;
+ cmdline = get_cmdline_by_pid(cur_pid);
+ if (cmdline == NULL) {
+ ret = CMD_ERROR;
+ goto error;
+ }
+ MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
+ free(cmdline);
+ /* Wipe current event since we are about to print a new PID. */
+ memset(&cur_event, 0, sizeof(cur_event));
+ }
+ if (strcmp(cur_event.name, event_field_list[i].event.name) != 0) {
+ print_events(&event_field_list[i].event);
+ memcpy(&cur_event, &event_field_list[i].event,
+ sizeof(cur_event));
+ }
+ print_event_field(&event_field_list[i]);
+ }
+
+ MSG("");
+ }