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;
}