#include <common/dynamic-buffer.h>
#include <common/utils.h>
#include <common/defaults.h>
-#include <assert.h>
+#include <common/payload.h>
+#include <common/payload-view.h>
+#include <common/unix.h>
#include "lttng-ctl-helper.h"
#include <common/compat/poll.h>
ssize_t ret;
struct lttng_notification_channel_message msg;
- if (lttng_dynamic_buffer_set_size(&channel->reception_buffer, 0)) {
- ret = -1;
- goto end;
- }
+ lttng_payload_clear(&channel->reception_payload);
ret = lttcomm_recv_unix_sock(channel->socket, &msg, sizeof(msg));
if (ret <= 0) {
}
/* Add message header at buffer's start. */
- ret = lttng_dynamic_buffer_append(&channel->reception_buffer, &msg,
+ ret = lttng_dynamic_buffer_append(&channel->reception_payload.buffer, &msg,
sizeof(msg));
if (ret) {
goto error;
}
/* Reserve space for the payload. */
- ret = lttng_dynamic_buffer_set_size(&channel->reception_buffer,
- channel->reception_buffer.size + msg.size);
+ ret = lttng_dynamic_buffer_set_size(&channel->reception_payload.buffer,
+ channel->reception_payload.buffer.size + msg.size);
if (ret) {
goto error;
}
/* Receive message payload. */
ret = lttcomm_recv_unix_sock(channel->socket,
- channel->reception_buffer.data + sizeof(msg), msg.size);
+ channel->reception_payload.buffer.data + sizeof(msg), msg.size);
if (ret < (ssize_t) msg.size) {
ret = -1;
goto error;
}
+
+ /* Receive message fds. */
+ if (msg.fds != 0) {
+ ret = lttcomm_recv_payload_fds_unix_sock(channel->socket,
+ msg.fds, &channel->reception_payload);
+ if (ret < sizeof(int) * msg.fds) {
+ ret = -1;
+ goto error;
+ }
+ }
ret = 0;
end:
return ret;
error:
- if (lttng_dynamic_buffer_set_size(&channel->reception_buffer, 0)) {
- ret = -1;
- }
+ lttng_payload_clear(&channel->reception_payload);
goto end;
}
{
struct lttng_notification_channel_message *msg;
- assert(channel->reception_buffer.size >= sizeof(*msg));
+ LTTNG_ASSERT(channel->reception_payload.buffer.size >= sizeof(*msg));
msg = (struct lttng_notification_channel_message *)
- channel->reception_buffer.data;
+ channel->reception_payload.buffer.data;
return (enum lttng_notification_channel_message_type) msg->type;
}
{
ssize_t ret;
struct lttng_notification *notification = NULL;
- struct lttng_buffer_view view;
- if (channel->reception_buffer.size <=
+ if (channel->reception_payload.buffer.size <=
sizeof(struct lttng_notification_channel_message)) {
goto end;
}
- view = lttng_buffer_view_from_dynamic_buffer(&channel->reception_buffer,
- sizeof(struct lttng_notification_channel_message), -1);
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(
+ &channel->reception_payload,
+ sizeof(struct lttng_notification_channel_message),
+ -1);
+
+ ret = lttng_notification_create_from_payload(
+ &view, ¬ification);
+ }
- ret = lttng_notification_create_from_buffer(&view, ¬ification);
- if (ret != channel->reception_buffer.size -
+ if (ret != channel->reception_payload.buffer.size -
sizeof(struct lttng_notification_channel_message)) {
lttng_notification_destroy(notification);
notification = NULL;
}
channel->socket = -1;
pthread_mutex_init(&channel->lock, NULL);
- lttng_dynamic_buffer_init(&channel->reception_buffer);
+ lttng_payload_init(&channel->reception_payload);
CDS_INIT_LIST_HEAD(&channel->pending_notifications.list);
is_root = (getuid() == 0);
}
if (is_root || is_in_tracing_group) {
- lttng_ctl_copy_string(sock_path,
+ ret = lttng_strncpy(sock_path,
DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK,
LTTNG_PATH_MAX);
+ if (ret) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
ret = lttcomm_connect_unix_sock(sock_path);
if (ret >= 0) {
fd = ret;
if (channel->pending_notifications.count) {
struct pending_notification *pending_notification;
- assert(!cds_list_empty(&channel->pending_notifications.list));
+ LTTNG_ASSERT(!cds_list_empty(&channel->pending_notifications.list));
/* Deliver one of the pending notifications. */
pending_notification = cds_list_first_entry(
struct lttng_notification_channel_command_handshake *handshake;
handshake = (struct lttng_notification_channel_command_handshake *)
- (channel->reception_buffer.data +
+ (channel->reception_payload.buffer.data +
sizeof(struct lttng_notification_channel_message));
channel->version.major = handshake->major;
channel->version.minor = handshake->minor;
}
exit_loop:
- if (channel->reception_buffer.size <
+ if (channel->reception_payload.buffer.size <
(sizeof(struct lttng_notification_channel_message) +
sizeof(*reply))) {
/* Invalid message received. */
}
reply = (struct lttng_notification_channel_command_reply *)
- (channel->reception_buffer.data +
+ (channel->reception_payload.buffer.data +
sizeof(struct lttng_notification_channel_message));
*status = (enum lttng_notification_channel_status) reply->status;
end:
ssize_t ret;
enum lttng_notification_channel_status status =
LTTNG_NOTIFICATION_CHANNEL_STATUS_OK;
- struct lttng_dynamic_buffer buffer;
+ struct lttng_payload payload;
struct lttng_notification_channel_message cmd_header = {
.type = (int8_t) type,
};
- lttng_dynamic_buffer_init(&buffer);
+ lttng_payload_init(&payload);
if (!channel) {
status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID;
goto end;
}
- assert(type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_SUBSCRIBE ||
+ LTTNG_ASSERT(type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_SUBSCRIBE ||
type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNSUBSCRIBE);
pthread_mutex_lock(&channel->lock);
socket = channel->socket;
+
if (!lttng_condition_validate(condition)) {
status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID;
goto end_unlock;
}
- ret = lttng_dynamic_buffer_append(&buffer, &cmd_header,
+ ret = lttng_dynamic_buffer_append(&payload.buffer, &cmd_header,
sizeof(cmd_header));
if (ret) {
status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
goto end_unlock;
}
- ret = lttng_condition_serialize(condition, &buffer);
+ ret = lttng_condition_serialize(condition, &payload);
if (ret) {
status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID;
goto end_unlock;
}
/* Update payload length. */
- ((struct lttng_notification_channel_message *) buffer.data)->size =
- (uint32_t) (buffer.size - sizeof(cmd_header));
+ ((struct lttng_notification_channel_message *) payload.buffer.data)->size =
+ (uint32_t) (payload.buffer.size - sizeof(cmd_header));
+
+ {
+ struct lttng_payload_view pv =
+ lttng_payload_view_from_payload(
+ &payload, 0, -1);
+ const int fd_count =
+ lttng_payload_view_get_fd_handle_count(&pv);
+
+ /* Update fd count. */
+ ((struct lttng_notification_channel_message *) payload.buffer.data)->fds =
+ (uint32_t) fd_count;
+
+ ret = lttcomm_send_unix_sock(
+ socket, pv.buffer.data, pv.buffer.size);
+ if (ret < 0) {
+ status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
+ goto end_unlock;
+ }
- ret = lttcomm_send_unix_sock(socket, buffer.data, buffer.size);
- if (ret < 0) {
- status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
- goto end_unlock;
+ /* Pass fds if present. */
+ if (fd_count > 0) {
+ ret = lttcomm_send_payload_view_fds_unix_sock(socket,
+ &pv);
+ if (ret < 0) {
+ status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;
+ goto end_unlock;
+ }
+ }
}
ret = receive_command_reply(channel, &status);
end_unlock:
pthread_mutex_unlock(&channel->lock);
end:
- lttng_dynamic_buffer_reset(&buffer);
+ lttng_payload_reset(&payload);
return status;
}
(void) lttcomm_close_unix_sock(channel->socket);
}
pthread_mutex_destroy(&channel->lock);
- lttng_dynamic_buffer_reset(&channel->reception_buffer);
+ lttng_payload_reset(&channel->reception_payload);
free(channel);
}