Fix the payload type returned by IPC
If a client is subscribed and sends a subsequent ipc command which causes event updates, then those event updates override the `client->current_command` and send the incorrect type for the payload associated with the command. Example: SUBSCRIBE {window} RUN_COMMAND focus -> PAYLOAD_TYPE is 0x80000002 for window events Therefore, we decouple the `client->current_command` by passing it as an argument to the ipc_send_reply function, avoiding a data race. The same is done for the `client->payload_length` as a precautionary measure for the same reason.
This commit is contained in:
parent
9ac2342a67
commit
aa4deef8a8
|
@ -47,13 +47,14 @@ struct ipc_client {
|
||||||
struct wl_event_source *writable_event_source;
|
struct wl_event_source *writable_event_source;
|
||||||
struct sway_server *server;
|
struct sway_server *server;
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t payload_length;
|
|
||||||
uint32_t security_policy;
|
uint32_t security_policy;
|
||||||
enum ipc_command_type current_command;
|
|
||||||
enum ipc_command_type subscribed_events;
|
enum ipc_command_type subscribed_events;
|
||||||
size_t write_buffer_len;
|
size_t write_buffer_len;
|
||||||
size_t write_buffer_size;
|
size_t write_buffer_size;
|
||||||
char *write_buffer;
|
char *write_buffer;
|
||||||
|
// The following are for storing data between event_loop calls
|
||||||
|
uint32_t pending_length;
|
||||||
|
enum ipc_command_type pending_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sockaddr_un *ipc_user_sockaddr(void);
|
struct sockaddr_un *ipc_user_sockaddr(void);
|
||||||
|
@ -61,8 +62,10 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data);
|
||||||
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
|
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
|
||||||
int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data);
|
int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data);
|
||||||
void ipc_client_disconnect(struct ipc_client *client);
|
void ipc_client_disconnect(struct ipc_client *client);
|
||||||
void ipc_client_handle_command(struct ipc_client *client);
|
void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_length,
|
||||||
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
|
enum ipc_command_type payload_type);
|
||||||
|
bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type,
|
||||||
|
const char *payload, uint32_t payload_length);
|
||||||
|
|
||||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||||
if (ipc_event_source) {
|
if (ipc_event_source) {
|
||||||
|
@ -178,7 +181,7 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
client->server = server;
|
client->server = server;
|
||||||
client->payload_length = 0;
|
client->pending_length = 0;
|
||||||
client->fd = client_fd;
|
client->fd = client_fd;
|
||||||
client->subscribed_events = 0;
|
client->subscribed_events = 0;
|
||||||
client->event_source = wl_event_loop_add_fd(server->wl_event_loop,
|
client->event_source = wl_event_loop_add_fd(server->wl_event_loop,
|
||||||
|
@ -224,9 +227,13 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the rest of the command payload in case the header has already been read
|
// Wait for the rest of the command payload in case the header has already been read
|
||||||
if (client->payload_length > 0) {
|
if (client->pending_length > 0) {
|
||||||
if ((uint32_t)read_available >= client->payload_length) {
|
if ((uint32_t)read_available >= client->pending_length) {
|
||||||
ipc_client_handle_command(client);
|
// Reset pending values.
|
||||||
|
uint32_t pending_length = client->pending_length;
|
||||||
|
enum ipc_command_type pending_type = client->pending_type;
|
||||||
|
client->pending_length = 0;
|
||||||
|
ipc_client_handle_command(client, pending_length, pending_type);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -251,11 +258,15 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&client->payload_length, &buf32[0], sizeof(buf32[0]));
|
memcpy(&client->pending_length, &buf32[0], sizeof(buf32[0]));
|
||||||
memcpy(&client->current_command, &buf32[1], sizeof(buf32[1]));
|
memcpy(&client->pending_type, &buf32[1], sizeof(buf32[1]));
|
||||||
|
|
||||||
if (read_available - received >= (long)client->payload_length) {
|
if (read_available - received >= (long)client->pending_length) {
|
||||||
ipc_client_handle_command(client);
|
// Reset pending values.
|
||||||
|
uint32_t pending_length = client->pending_length;
|
||||||
|
enum ipc_command_type pending_type = client->pending_type;
|
||||||
|
client->pending_length = 0;
|
||||||
|
ipc_client_handle_command(client, pending_length, pending_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -278,8 +289,8 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event)
|
||||||
if ((client->subscribed_events & event_mask(event)) == 0) {
|
if ((client->subscribed_events & event_mask(event)) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
client->current_command = event;
|
if (!ipc_send_reply(client, event, json_string,
|
||||||
if (!ipc_send_reply(client, json_string, (uint32_t) strlen(json_string))) {
|
(uint32_t)strlen(json_string))) {
|
||||||
sway_log_errno(SWAY_INFO, "Unable to send reply to IPC client");
|
sway_log_errno(SWAY_INFO, "Unable to send reply to IPC client");
|
||||||
/* ipc_send_reply destroys client on error, which also
|
/* ipc_send_reply destroys client on error, which also
|
||||||
* removes it from the list, so we need to process
|
* removes it from the list, so we need to process
|
||||||
|
@ -567,20 +578,21 @@ static void ipc_get_marks_callback(struct sway_container *con, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_client_handle_command(struct ipc_client *client) {
|
void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_length,
|
||||||
|
enum ipc_command_type payload_type) {
|
||||||
if (!sway_assert(client != NULL, "client != NULL")) {
|
if (!sway_assert(client != NULL, "client != NULL")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf = malloc(client->payload_length + 1);
|
char *buf = malloc(payload_length + 1);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
sway_log_errno(SWAY_INFO, "Unable to allocate IPC payload");
|
sway_log_errno(SWAY_INFO, "Unable to allocate IPC payload");
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (client->payload_length > 0) {
|
if (payload_length > 0) {
|
||||||
// Payload should be fully available
|
// Payload should be fully available
|
||||||
ssize_t received = recv(client->fd, buf, client->payload_length, 0);
|
ssize_t received = recv(client->fd, buf, payload_length, 0);
|
||||||
if (received == -1)
|
if (received == -1)
|
||||||
{
|
{
|
||||||
sway_log_errno(SWAY_INFO, "Unable to receive payload from IPC client");
|
sway_log_errno(SWAY_INFO, "Unable to receive payload from IPC client");
|
||||||
|
@ -589,16 +601,15 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[client->payload_length] = '\0';
|
buf[payload_length] = '\0';
|
||||||
|
|
||||||
bool client_valid = true;
|
switch (payload_type) {
|
||||||
switch (client->current_command) {
|
|
||||||
case IPC_COMMAND:
|
case IPC_COMMAND:
|
||||||
{
|
{
|
||||||
char *line = strtok(buf, "\n");
|
char *line = strtok(buf, "\n");
|
||||||
while (line) {
|
while (line) {
|
||||||
size_t line_length = strlen(line);
|
size_t line_length = strlen(line);
|
||||||
if (line + line_length >= buf + client->payload_length) {
|
if (line + line_length >= buf + payload_length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line[line_length] = ';';
|
line[line_length] = ';';
|
||||||
|
@ -609,7 +620,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
char *json = cmd_results_to_json(res_list);
|
char *json = cmd_results_to_json(res_list);
|
||||||
int length = strlen(json);
|
int length = strlen(json);
|
||||||
client_valid = ipc_send_reply(client, json, (uint32_t)length);
|
ipc_send_reply(client, payload_type, json, (uint32_t)length);
|
||||||
free(json);
|
free(json);
|
||||||
while (res_list->length) {
|
while (res_list->length) {
|
||||||
struct cmd_results *results = res_list->items[0];
|
struct cmd_results *results = res_list->items[0];
|
||||||
|
@ -623,7 +634,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
case IPC_SEND_TICK:
|
case IPC_SEND_TICK:
|
||||||
{
|
{
|
||||||
ipc_event_tick(buf);
|
ipc_event_tick(buf);
|
||||||
ipc_send_reply(client, "{\"success\": true}", 17);
|
ipc_send_reply(client, payload_type, "{\"success\": true}", 17);
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,8 +667,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char *json_string = json_object_to_json_string(outputs);
|
const char *json_string = json_object_to_json_string(outputs);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(outputs); // free
|
json_object_put(outputs); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -667,8 +678,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object *workspaces = json_object_new_array();
|
json_object *workspaces = json_object_new_array();
|
||||||
root_for_each_workspace(ipc_get_workspaces_callback, workspaces);
|
root_for_each_workspace(ipc_get_workspaces_callback, workspaces);
|
||||||
const char *json_string = json_object_to_json_string(workspaces);
|
const char *json_string = json_object_to_json_string(workspaces);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(workspaces); // free
|
json_object_put(workspaces); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -679,7 +690,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
struct json_object *request = json_tokener_parse(buf);
|
struct json_object *request = json_tokener_parse(buf);
|
||||||
if (request == NULL || !json_object_is_type(request, json_type_array)) {
|
if (request == NULL || !json_object_is_type(request, json_type_array)) {
|
||||||
const char msg[] = "{\"success\": false}";
|
const char msg[] = "{\"success\": false}";
|
||||||
client_valid = ipc_send_reply(client, msg, strlen(msg));
|
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||||
sway_log(SWAY_INFO, "Failed to parse subscribe request");
|
sway_log(SWAY_INFO, "Failed to parse subscribe request");
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -707,7 +718,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
is_tick = true;
|
is_tick = true;
|
||||||
} else {
|
} else {
|
||||||
const char msg[] = "{\"success\": false}";
|
const char msg[] = "{\"success\": false}";
|
||||||
client_valid = ipc_send_reply(client, msg, strlen(msg));
|
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||||
json_object_put(request);
|
json_object_put(request);
|
||||||
sway_log(SWAY_INFO, "Unsupported event type in subscribe request");
|
sway_log(SWAY_INFO, "Unsupported event type in subscribe request");
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
|
@ -716,11 +727,11 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
|
|
||||||
json_object_put(request);
|
json_object_put(request);
|
||||||
const char msg[] = "{\"success\": true}";
|
const char msg[] = "{\"success\": true}";
|
||||||
client_valid = ipc_send_reply(client, msg, strlen(msg));
|
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||||
if (is_tick) {
|
if (is_tick) {
|
||||||
client->current_command = IPC_EVENT_TICK;
|
|
||||||
const char tickmsg[] = "{\"first\": true, \"payload\": \"\"}";
|
const char tickmsg[] = "{\"first\": true, \"payload\": \"\"}";
|
||||||
ipc_send_reply(client, tickmsg, strlen(tickmsg));
|
ipc_send_reply(client, IPC_EVENT_TICK, tickmsg,
|
||||||
|
strlen(tickmsg));
|
||||||
}
|
}
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -733,8 +744,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object_array_add(inputs, ipc_json_describe_input(device));
|
json_object_array_add(inputs, ipc_json_describe_input(device));
|
||||||
}
|
}
|
||||||
const char *json_string = json_object_to_json_string(inputs);
|
const char *json_string = json_object_to_json_string(inputs);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(inputs); // free
|
json_object_put(inputs); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -747,8 +758,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object_array_add(seats, ipc_json_describe_seat(seat));
|
json_object_array_add(seats, ipc_json_describe_seat(seat));
|
||||||
}
|
}
|
||||||
const char *json_string = json_object_to_json_string(seats);
|
const char *json_string = json_object_to_json_string(seats);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(seats); // free
|
json_object_put(seats); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -757,8 +768,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
{
|
{
|
||||||
json_object *tree = ipc_json_describe_node_recursive(&root->node);
|
json_object *tree = ipc_json_describe_node_recursive(&root->node);
|
||||||
const char *json_string = json_object_to_json_string(tree);
|
const char *json_string = json_object_to_json_string(tree);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(tree);
|
json_object_put(tree);
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -768,8 +779,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object *marks = json_object_new_array();
|
json_object *marks = json_object_new_array();
|
||||||
root_for_each_container(ipc_get_marks_callback, marks);
|
root_for_each_container(ipc_get_marks_callback, marks);
|
||||||
const char *json_string = json_object_to_json_string(marks);
|
const char *json_string = json_object_to_json_string(marks);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(marks);
|
json_object_put(marks);
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -778,8 +789,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
{
|
{
|
||||||
json_object *version = ipc_json_get_version();
|
json_object *version = ipc_json_get_version();
|
||||||
const char *json_string = json_object_to_json_string(version);
|
const char *json_string = json_object_to_json_string(version);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(version); // free
|
json_object_put(version); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -794,8 +805,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object_array_add(bars, json_object_new_string(bar->id));
|
json_object_array_add(bars, json_object_new_string(bar->id));
|
||||||
}
|
}
|
||||||
const char *json_string = json_object_to_json_string(bars);
|
const char *json_string = json_object_to_json_string(bars);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string,
|
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(bars); // free
|
json_object_put(bars); // free
|
||||||
} else {
|
} else {
|
||||||
|
@ -810,14 +820,13 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
}
|
}
|
||||||
if (!bar) {
|
if (!bar) {
|
||||||
const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
|
const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, error,
|
||||||
ipc_send_reply(client, error, (uint32_t)strlen(error));
|
(uint32_t)strlen(error));
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
json_object *json = ipc_json_describe_bar_config(bar);
|
json_object *json = ipc_json_describe_bar_config(bar);
|
||||||
const char *json_string = json_object_to_json_string(json);
|
const char *json_string = json_object_to_json_string(json);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string,
|
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(json); // free
|
json_object_put(json); // free
|
||||||
}
|
}
|
||||||
|
@ -832,8 +841,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object_array_add(modes, json_object_new_string(mode->name));
|
json_object_array_add(modes, json_object_new_string(mode->name));
|
||||||
}
|
}
|
||||||
const char *json_string = json_object_to_json_string(modes);
|
const char *json_string = json_object_to_json_string(modes);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(modes); // free
|
json_object_put(modes); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -843,8 +852,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
json_object *json = json_object_new_object();
|
json_object *json = json_object_new_object();
|
||||||
json_object_object_add(json, "config", json_object_new_string(config->current_config));
|
json_object_object_add(json, "config", json_object_new_string(config->current_config));
|
||||||
const char *json_string = json_object_to_json_string(json);
|
const char *json_string = json_object_to_json_string(json);
|
||||||
client_valid =
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(json); // free
|
json_object_put(json); // free
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -853,24 +862,22 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
{
|
{
|
||||||
// It was decided sway will not support this, just return success:false
|
// It was decided sway will not support this, just return success:false
|
||||||
const char msg[] = "{\"success\": false}";
|
const char msg[] = "{\"success\": false}";
|
||||||
ipc_send_reply(client, msg, strlen(msg));
|
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sway_log(SWAY_INFO, "Unknown IPC command type %i", client->current_command);
|
sway_log(SWAY_INFO, "Unknown IPC command type %x", payload_type);
|
||||||
goto exit_cleanup;
|
goto exit_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_cleanup:
|
exit_cleanup:
|
||||||
if (client_valid) {
|
|
||||||
client->payload_length = 0;
|
|
||||||
}
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length) {
|
bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type,
|
||||||
|
const char *payload, uint32_t payload_length) {
|
||||||
assert(payload);
|
assert(payload);
|
||||||
|
|
||||||
char data[IPC_HEADER_SIZE];
|
char data[IPC_HEADER_SIZE];
|
||||||
|
@ -878,7 +885,7 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
|
||||||
|
|
||||||
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||||
memcpy(&data32[0], &payload_length, sizeof(payload_length));
|
memcpy(&data32[0], &payload_length, sizeof(payload_length));
|
||||||
memcpy(&data32[1], &client->current_command, sizeof(client->current_command));
|
memcpy(&data32[1], &payload_type, sizeof(payload_type));
|
||||||
|
|
||||||
while (client->write_buffer_len + IPC_HEADER_SIZE + payload_length >=
|
while (client->write_buffer_len + IPC_HEADER_SIZE + payload_length >=
|
||||||
client->write_buffer_size) {
|
client->write_buffer_size) {
|
||||||
|
@ -910,6 +917,7 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
|
||||||
ipc_client_handle_writable, client);
|
ipc_client_handle_writable, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Added IPC reply to client %d queue: %s", client->fd, payload);
|
sway_log(SWAY_DEBUG, "Added IPC reply of type 0x%x to client %d queue: %s",
|
||||||
|
payload_type, client->fd, payload);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue