Basic serialization/deserialization for lttng_session
[deliverable/lttng-tools.git] / src / lib / lttng-ctl / lttng-ctl.cpp
index 3d0c8b412cc7297914051a3417831d417857bf28..9dff22a2bca57e1b7c22cc612ef96d36aa40bb63 100644 (file)
@@ -2211,51 +2211,59 @@ int lttng_destroy_session_no_wait(const char *session_name)
 int lttng_list_sessions(struct lttng_session **out_sessions)
 {
        int ret;
-       struct lttcomm_session_msg lsm;
-       const size_t session_size = sizeof(struct lttng_session) +
-                       sizeof(struct lttng_session_extended);
-       size_t session_count, i;
-       struct lttng_session_extended *sessions_extended_begin;
-       struct lttng_session *sessions = NULL;
+       struct lttcomm_session_msg lsm = {};
+       struct lttng_payload reply;
+       struct lttng_payload_view lsm_view =
+                       lttng_payload_view_init_from_buffer((const char *) &lsm, 0, sizeof(lsm));
+       unsigned int nb_sessions = 0;
 
-       memset(&lsm, 0, sizeof(lsm));
+       lttng_payload_init(&reply);
+
+       /* Initialize command parameters. */
        lsm.cmd_type = LTTNG_LIST_SESSIONS;
-       /*
-        * Initialize out_sessions to NULL so it is initialized when
-        * lttng_list_sessions returns 0, thus allowing *out_sessions to
-        * be subsequently freed.
-        */
-       *out_sessions = NULL;
-       ret = lttng_ctl_ask_sessiond(&lsm, (void**) &sessions);
-       if (ret <= 0) {
-               goto end;
-       }
-       if (!sessions) {
-               ret = -LTTNG_ERR_FATAL;
+
+       /* Execute command against the session daemon. */
+       ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &reply);
+       if (ret < 0) {
                goto end;
        }
 
-       if (ret % session_size) {
-               ret = -LTTNG_ERR_UNK;
-               free(sessions);
-               goto end;
+       {
+               const struct lttcomm_list_command_header *cmd_reply_header = NULL;
+               const lttng_payload_view cmd_reply_header_view = lttng_payload_view_from_payload(
+                               &reply, 0, sizeof(*cmd_reply_header));
+
+               if (!lttng_payload_view_is_valid(&cmd_reply_header_view)) {
+                       ret = -LTTNG_ERR_INVALID_PROTOCOL;
+                       goto end;
+               }
+
+               cmd_reply_header = (const struct lttcomm_list_command_header *)
+                                                  cmd_reply_header_view.buffer.data;
+               if (cmd_reply_header->count > INT_MAX) {
+                       ret = -LTTNG_ERR_OVERFLOW;
+                       goto end;
+               }
+
+               nb_sessions = (unsigned int) cmd_reply_header->count;
        }
-       session_count = (size_t) ret / session_size;
-       sessions_extended_begin = (struct lttng_session_extended *)
-                       (&sessions[session_count]);
 
-       /* Set extended session info pointers. */
-       for (i = 0; i < session_count; i++) {
-               struct lttng_session *session = &sessions[i];
-               struct lttng_session_extended *extended =
-                               &(sessions_extended_begin[i]);
+       {
+               enum lttng_error_code ret_code;
+               lttng_payload_view cmd_reply_payload = lttng_payload_view_from_payload(
+                               &reply, sizeof(struct lttcomm_list_command_header), -1);
 
-               session->extended.ptr = extended;
+               ret_code = lttng_sessions_create_and_flatten_from_payload(
+                               &cmd_reply_payload, nb_sessions, out_sessions);
+               if (ret_code != LTTNG_OK) {
+                       ret = -((int) ret_code);
+                       goto end;
+               }
        }
 
-       ret = (int) session_count;
-       *out_sessions = sessions;
+       ret = (int) nb_sessions;
 end:
+       lttng_payload_reset(&reply);
        return ret;
 }
 
This page took 0.037625 seconds and 5 git commands to generate.