+static enum lttng_error_code receive_lttng_event(struct command_ctx *cmd_ctx,
+ int sock,
+ int *sock_error,
+ struct lttng_event **out_event,
+ char **out_filter_expression,
+ struct lttng_bytecode **out_bytecode,
+ struct lttng_event_exclusion **out_exclusion)
+{
+ int ret;
+ size_t event_len;
+ ssize_t sock_recv_len;
+ enum lttng_error_code ret_code;
+ struct lttng_payload event_payload;
+ struct lttng_event *local_event = NULL;
+ char *local_filter_expression = NULL;
+ struct lttng_bytecode *local_bytecode = NULL;
+ struct lttng_event_exclusion *local_exclusion = NULL;
+
+ lttng_payload_init(&event_payload);
+ if (cmd_ctx->lsm.cmd_type == LTTCOMM_SESSIOND_COMMAND_ENABLE_EVENT) {
+ event_len = (size_t) cmd_ctx->lsm.u.enable.length;
+ } else if (cmd_ctx->lsm.cmd_type == LTTCOMM_SESSIOND_COMMAND_DISABLE_EVENT) {
+ event_len = (size_t) cmd_ctx->lsm.u.disable.length;
+ } else {
+ abort();
+ }
+
+ ret = lttng_dynamic_buffer_set_size(&event_payload.buffer, event_len);
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ sock_recv_len = lttcomm_recv_unix_sock(sock, event_payload.buffer.data, event_len);
+ if (sock_recv_len < 0 || sock_recv_len != event_len) {
+ ERR("Failed to receive event in command payload");
+ *sock_error = 1;
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ /* Receive fds, if any. */
+ if (cmd_ctx->lsm.fd_count > 0) {
+ sock_recv_len = lttcomm_recv_payload_fds_unix_sock(
+ sock, cmd_ctx->lsm.fd_count, &event_payload);
+ if (sock_recv_len > 0 && sock_recv_len != cmd_ctx->lsm.fd_count * sizeof(int)) {
+ ERR("Failed to receive all file descriptors for event in command payload: expected fd count = %u, ret = %d",
+ cmd_ctx->lsm.fd_count,
+ (int) ret);
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ *sock_error = 1;
+ goto end;
+ } else if (sock_recv_len <= 0) {
+ ERR("Failed to receive file descriptors for event in command payload: expected fd count = %u, ret = %d",
+ cmd_ctx->lsm.fd_count,
+ (int) ret);
+ ret_code = LTTNG_ERR_FATAL;
+ *sock_error = 1;
+ goto end;
+ }
+ }
+
+ /* Deserialize event. */
+ {
+ ssize_t len;
+ struct lttng_payload_view event_view =
+ lttng_payload_view_from_payload(&event_payload, 0, -1);
+
+ len = lttng_event_create_from_payload(&event_view,
+ &local_event,
+ &local_exclusion,
+ &local_filter_expression,
+ &local_bytecode);
+
+ if (len < 0) {
+ ERR("Failed to create an event from the received buffer");
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ if (len != event_len) {
+ ERR("Userspace probe location from the received buffer is not the advertised length: header length = %zu" PRIu32
+ ", payload length = %zd",
+ event_len,
+ len);
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+ }
+
+ *out_event = local_event;
+ *out_exclusion = local_exclusion;
+ *out_filter_expression = local_filter_expression;
+ *out_bytecode = local_bytecode;
+ local_event = NULL;
+ local_exclusion = NULL;
+ local_filter_expression = NULL;
+ local_bytecode = NULL;
+
+ ret_code = LTTNG_OK;
+
+end:
+ lttng_payload_reset(&event_payload);
+ lttng_event_destroy(local_event);
+ free(local_filter_expression);
+ free(local_bytecode);
+ free(local_exclusion);
+ return ret_code;
+}
+
+static enum lttng_error_code
+receive_lttng_event_context(const struct command_ctx *cmd_ctx,
+ int sock,
+ int *sock_error,
+ struct lttng_event_context **out_event_context)
+{
+ int ret;
+ const size_t event_context_len = (size_t) cmd_ctx->lsm.u.context.length;
+ ssize_t sock_recv_len;
+ enum lttng_error_code ret_code;
+ struct lttng_payload event_context_payload;
+ struct lttng_event_context *context = NULL;
+
+ lttng_payload_init(&event_context_payload);
+
+ ret = lttng_dynamic_buffer_set_size(&event_context_payload.buffer, event_context_len);
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ sock_recv_len =
+ lttcomm_recv_unix_sock(sock, event_context_payload.buffer.data, event_context_len);
+ if (sock_recv_len < 0 || sock_recv_len != event_context_len) {
+ ERR("Failed to receive event context in command payload");
+ *sock_error = 1;
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ /* Deserialize event. */
+ {
+ ssize_t len;
+ struct lttng_payload_view event_context_view =
+ lttng_payload_view_from_payload(&event_context_payload, 0, -1);
+
+ len = lttng_event_context_create_from_payload(&event_context_view, &context);
+
+ if (len < 0) {
+ ERR("Failed to create a event context from the received buffer");
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ if (len != event_context_len) {
+ ERR("Event context from the received buffer is not the advertised length: expected length = %zu, payload length = %zd",
+ event_context_len,
+ len);
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+ }
+
+ *out_event_context = context;
+ context = NULL;
+ ret_code = LTTNG_OK;
+
+end:
+ lttng_event_context_destroy(context);
+ lttng_payload_reset(&event_context_payload);
+ return ret_code;
+}
+