mirror of
https://github.com/swaywm/sway.git
synced 2026-04-22 06:46:27 -04:00
Merge 3e69928f13 into c32a507303
This commit is contained in:
commit
df9b88befb
7 changed files with 131 additions and 86 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -94,9 +95,15 @@ struct ipc_response *ipc_recv_response(int socketfd) {
|
||||||
goto error_1;
|
goto error_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&response->size, data + sizeof(ipc_magic), sizeof(uint32_t));
|
uint32_t size;
|
||||||
|
memcpy(&size, data + sizeof(ipc_magic), sizeof(uint32_t));
|
||||||
|
response->size = size;
|
||||||
memcpy(&response->type, data + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
memcpy(&response->type, data + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
||||||
|
|
||||||
|
if (response->size >= SSIZE_MAX) {
|
||||||
|
sway_abort("Unable to receive overly long IPC response");
|
||||||
|
}
|
||||||
|
|
||||||
char *payload = malloc(response->size + 1);
|
char *payload = malloc(response->size + 1);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
goto error_2;
|
goto error_2;
|
||||||
|
|
@ -126,11 +133,16 @@ void free_ipc_response(struct ipc_response *response) {
|
||||||
free(response);
|
free(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
|
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, size_t *len) {
|
||||||
char data[IPC_HEADER_SIZE];
|
char data[IPC_HEADER_SIZE];
|
||||||
|
|
||||||
|
if (*len > UINT32_MAX) {
|
||||||
|
sway_abort("Unable to send overly long IPC payload");
|
||||||
|
}
|
||||||
|
uint32_t size = *len;
|
||||||
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||||
memcpy(data + sizeof(ipc_magic), len, sizeof(*len));
|
memcpy(data + sizeof(ipc_magic), &size, sizeof(size));
|
||||||
memcpy(data + sizeof(ipc_magic) + sizeof(*len), &type, sizeof(type));
|
memcpy(data + sizeof(ipc_magic) + sizeof(size), &type, sizeof(type));
|
||||||
|
|
||||||
if (write(socketfd, data, IPC_HEADER_SIZE) == -1) {
|
if (write(socketfd, data, IPC_HEADER_SIZE) == -1) {
|
||||||
sway_abort("Unable to send IPC header");
|
sway_abort("Unable to send IPC header");
|
||||||
|
|
@ -141,9 +153,15 @@ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint3
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipc_response *resp = ipc_recv_response(socketfd);
|
struct ipc_response *resp = ipc_recv_response(socketfd);
|
||||||
char *response = resp->payload;
|
char *response;
|
||||||
*len = resp->size;
|
if (resp == NULL) {
|
||||||
free(resp);
|
response = NULL;
|
||||||
|
*len = 0;
|
||||||
|
} else {
|
||||||
|
response = resp->payload;
|
||||||
|
*len = resp->size;
|
||||||
|
free(resp);
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* encoded payload string.
|
* encoded payload string.
|
||||||
*/
|
*/
|
||||||
struct ipc_response {
|
struct ipc_response {
|
||||||
uint32_t size;
|
size_t size;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
char *payload;
|
char *payload;
|
||||||
};
|
};
|
||||||
|
|
@ -32,7 +32,7 @@ int ipc_open_socket(const char *socket_path);
|
||||||
* Issues a single IPC command and returns the buffer. len will be updated with
|
* Issues a single IPC command and returns the buffer. len will be updated with
|
||||||
* the length of the buffer returned from sway.
|
* the length of the buffer returned from sway.
|
||||||
*/
|
*/
|
||||||
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len);
|
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, size_t *len);
|
||||||
/**
|
/**
|
||||||
* Receives a single IPC response and returns an ipc_response.
|
* Receives a single IPC response and returns an ipc_response.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#define event_mask(ev) (1 << (ev & 0x7F))
|
#define event_mask(ev) (1 << (ev & 0x7F))
|
||||||
|
|
||||||
|
// maximum size of payload is 4 MB
|
||||||
|
#define IPC_MAX_SIZE 4e6
|
||||||
|
|
||||||
enum ipc_command_type {
|
enum ipc_command_type {
|
||||||
// i3 command types - see i3's I3_REPLY_TYPE constants
|
// i3 command types - see i3's I3_REPLY_TYPE constants
|
||||||
IPC_COMMAND = 0,
|
IPC_COMMAND = 0,
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ struct ipc_client {
|
||||||
struct sway_server *server;
|
struct sway_server *server;
|
||||||
int fd;
|
int fd;
|
||||||
enum ipc_command_type subscribed_events;
|
enum ipc_command_type subscribed_events;
|
||||||
|
size_t read_buffer_len;
|
||||||
|
size_t read_buffer_size;
|
||||||
|
char *read_buffer;
|
||||||
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;
|
||||||
|
|
@ -186,11 +189,23 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
||||||
client_fd, WL_EVENT_READABLE, ipc_client_handle_readable, client);
|
client_fd, WL_EVENT_READABLE, ipc_client_handle_readable, client);
|
||||||
client->writable_event_source = NULL;
|
client->writable_event_source = NULL;
|
||||||
|
|
||||||
|
client->read_buffer_size = 128;
|
||||||
|
client->read_buffer_len = 0;
|
||||||
|
client->read_buffer = malloc(client->read_buffer_size);
|
||||||
|
if (!client->read_buffer) {
|
||||||
|
sway_log(SWAY_ERROR, "Unable to allocate ipc client read buffer");
|
||||||
|
free(client);
|
||||||
|
close(client_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
client->write_buffer_size = 128;
|
client->write_buffer_size = 128;
|
||||||
client->write_buffer_len = 0;
|
client->write_buffer_len = 0;
|
||||||
client->write_buffer = malloc(client->write_buffer_size);
|
client->write_buffer = malloc(client->write_buffer_size);
|
||||||
if (!client->write_buffer) {
|
if (!client->write_buffer) {
|
||||||
sway_log(SWAY_ERROR, "Unable to allocate ipc client write buffer");
|
sway_log(SWAY_ERROR, "Unable to allocate ipc client write buffer");
|
||||||
|
free(client->read_buffer);
|
||||||
|
free(client);
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -220,49 +235,67 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if ((size_t)read_available + 1 > SIZE_MAX - client->read_buffer_len) {
|
||||||
|
sway_log_errno(SWAY_INFO, "Receiving too much data from IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the rest of the command payload in case the header has already been read
|
if (client->read_buffer_len + read_available >= client->read_buffer_size) {
|
||||||
if (client->pending_length > 0) {
|
size_t new_size = client->read_buffer_len + read_available + 1;
|
||||||
if ((uint32_t)read_available >= client->pending_length) {
|
char *new_buffer = realloc(client->read_buffer, new_size);
|
||||||
// Reset pending values.
|
if (new_buffer == NULL) {
|
||||||
uint32_t pending_length = client->pending_length;
|
sway_log_errno(SWAY_INFO, "Unable to increase read buffer for IPC client");
|
||||||
enum ipc_command_type pending_type = client->pending_type;
|
ipc_client_disconnect(client);
|
||||||
client->pending_length = 0;
|
return 0;
|
||||||
ipc_client_handle_command(client, pending_length, pending_type);
|
|
||||||
}
|
}
|
||||||
return 0;
|
client->read_buffer = new_buffer;
|
||||||
|
client->read_buffer_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_available < (int) IPC_HEADER_SIZE) {
|
ssize_t received = recv(client_fd, client->read_buffer + client->read_buffer_len, read_available, 0);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t buf[IPC_HEADER_SIZE];
|
|
||||||
// Should be fully available, because read_available >= IPC_HEADER_SIZE
|
|
||||||
ssize_t received = recv(client_fd, buf, IPC_HEADER_SIZE, 0);
|
|
||||||
if (received == -1) {
|
if (received == -1) {
|
||||||
sway_log_errno(SWAY_INFO, "Unable to receive header from IPC client");
|
sway_log_errno(SWAY_INFO, "Unable to receive header from IPC client");
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
client->read_buffer_len += received;
|
||||||
|
|
||||||
if (memcmp(buf, ipc_magic, sizeof(ipc_magic)) != 0) {
|
if (client->pending_length == 0) {
|
||||||
sway_log(SWAY_DEBUG, "IPC header check failed");
|
if (client->read_buffer_len < (size_t) IPC_HEADER_SIZE) {
|
||||||
ipc_client_disconnect(client);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
if (memcmp(client->read_buffer, ipc_magic, sizeof(ipc_magic)) != 0) {
|
||||||
|
sway_log(SWAY_DEBUG, "IPC header check failed");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&client->pending_length,
|
||||||
|
client->read_buffer + sizeof(ipc_magic), sizeof(uint32_t));
|
||||||
|
memcpy(&client->pending_type,
|
||||||
|
client->read_buffer + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
||||||
|
if (client->pending_length > IPC_MAX_SIZE) {
|
||||||
|
sway_log_errno(SWAY_INFO, "Receiving too much payload from IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&client->pending_length, buf + sizeof(ipc_magic), sizeof(uint32_t));
|
if (client->read_buffer_len >= IPC_HEADER_SIZE + client->pending_length) {
|
||||||
memcpy(&client->pending_type, buf + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
|
||||||
|
|
||||||
if (read_available - received >= (long)client->pending_length) {
|
|
||||||
// Reset pending values.
|
|
||||||
uint32_t pending_length = client->pending_length;
|
uint32_t pending_length = client->pending_length;
|
||||||
enum ipc_command_type pending_type = client->pending_type;
|
enum ipc_command_type pending_type = client->pending_type;
|
||||||
client->pending_length = 0;
|
char c = client->read_buffer[IPC_HEADER_SIZE + client->pending_length];
|
||||||
|
client->read_buffer[IPC_HEADER_SIZE + client->pending_length] = '\0';
|
||||||
ipc_client_handle_command(client, pending_length, pending_type);
|
ipc_client_handle_command(client, pending_length, pending_type);
|
||||||
|
// Reset values.
|
||||||
|
client->read_buffer[IPC_HEADER_SIZE + client->pending_length] = c;
|
||||||
|
memmove(client->read_buffer, client->read_buffer + IPC_HEADER_SIZE + client->pending_length,
|
||||||
|
client->read_buffer_len - IPC_HEADER_SIZE - client->pending_length);
|
||||||
|
client->read_buffer_len -= IPC_HEADER_SIZE + client->pending_length;
|
||||||
|
client->pending_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,6 +598,7 @@ void ipc_client_disconnect(struct ipc_client *client) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
list_del(ipc_client_list, i);
|
list_del(ipc_client_list, i);
|
||||||
|
free(client->read_buffer);
|
||||||
free(client->write_buffer);
|
free(client->write_buffer);
|
||||||
close(client->fd);
|
close(client->fd);
|
||||||
free(client);
|
free(client);
|
||||||
|
|
@ -603,24 +637,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf = malloc(payload_length + 1);
|
char *buf = client->read_buffer + IPC_HEADER_SIZE;
|
||||||
if (!buf) {
|
|
||||||
sway_log_errno(SWAY_INFO, "Unable to allocate IPC payload");
|
|
||||||
ipc_client_disconnect(client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (payload_length > 0) {
|
|
||||||
// Payload should be fully available
|
|
||||||
ssize_t received = recv(client->fd, buf, payload_length, 0);
|
|
||||||
if (received == -1)
|
|
||||||
{
|
|
||||||
sway_log_errno(SWAY_INFO, "Unable to receive payload from IPC client");
|
|
||||||
ipc_client_disconnect(client);
|
|
||||||
free(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf[payload_length] = '\0';
|
|
||||||
|
|
||||||
switch (payload_type) {
|
switch (payload_type) {
|
||||||
case IPC_COMMAND:
|
case IPC_COMMAND:
|
||||||
|
|
@ -647,14 +664,14 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
list_del(res_list, 0);
|
list_del(res_list, 0);
|
||||||
}
|
}
|
||||||
list_free(res_list);
|
list_free(res_list);
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_SEND_TICK:
|
case IPC_SEND_TICK:
|
||||||
{
|
{
|
||||||
ipc_event_tick(buf);
|
ipc_event_tick(buf);
|
||||||
ipc_send_reply(client, payload_type, "{\"success\": true}", 17);
|
ipc_send_reply(client, payload_type, "{\"success\": true}", 17);
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_OUTPUTS:
|
case IPC_GET_OUTPUTS:
|
||||||
|
|
@ -695,7 +712,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_WORKSPACES:
|
case IPC_GET_WORKSPACES:
|
||||||
|
|
@ -706,7 +723,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_SUBSCRIBE:
|
case IPC_SUBSCRIBE:
|
||||||
|
|
@ -717,7 +734,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
const char msg[] = "{\"success\": false}";
|
const char msg[] = "{\"success\": false}";
|
||||||
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_tick = false;
|
bool is_tick = false;
|
||||||
|
|
@ -748,7 +765,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -760,7 +777,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, IPC_EVENT_TICK, tickmsg,
|
ipc_send_reply(client, IPC_EVENT_TICK, tickmsg,
|
||||||
strlen(tickmsg));
|
strlen(tickmsg));
|
||||||
}
|
}
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_INPUTS:
|
case IPC_GET_INPUTS:
|
||||||
|
|
@ -774,7 +791,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_SEATS:
|
case IPC_GET_SEATS:
|
||||||
|
|
@ -788,7 +805,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_TREE:
|
case IPC_GET_TREE:
|
||||||
|
|
@ -798,7 +815,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(tree);
|
json_object_put(tree);
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_MARKS:
|
case IPC_GET_MARKS:
|
||||||
|
|
@ -809,7 +826,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(marks);
|
json_object_put(marks);
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_VERSION:
|
case IPC_GET_VERSION:
|
||||||
|
|
@ -819,7 +836,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_BAR_CONFIG:
|
case IPC_GET_BAR_CONFIG:
|
||||||
|
|
@ -849,7 +866,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
|
const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
|
||||||
ipc_send_reply(client, payload_type, error,
|
ipc_send_reply(client, payload_type, error,
|
||||||
(uint32_t)strlen(error));
|
(uint32_t)strlen(error));
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
@ -857,7 +874,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(json); // free
|
json_object_put(json); // free
|
||||||
}
|
}
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_BINDING_MODES:
|
case IPC_GET_BINDING_MODES:
|
||||||
|
|
@ -871,7 +888,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_BINDING_STATE:
|
case IPC_GET_BINDING_STATE:
|
||||||
|
|
@ -881,7 +898,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, json_string,
|
||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(current_mode); // free
|
json_object_put(current_mode); // free
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_CONFIG:
|
case IPC_GET_CONFIG:
|
||||||
|
|
@ -892,7 +909,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
ipc_send_reply(client, payload_type, json_string,
|
ipc_send_reply(client, payload_type, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_SYNC:
|
case IPC_SYNC:
|
||||||
|
|
@ -900,17 +917,13 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||||
// 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, payload_type, msg, strlen(msg));
|
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sway_log(SWAY_INFO, "Unknown IPC command type %x", payload_type);
|
sway_log(SWAY_INFO, "Unknown IPC command type %x", payload_type);
|
||||||
goto exit_cleanup;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_cleanup:
|
|
||||||
free(buf);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type,
|
bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type,
|
||||||
|
|
@ -928,7 +941,7 @@ bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_typ
|
||||||
client->write_buffer_size *= 2;
|
client->write_buffer_size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->write_buffer_size > 4e6) { // 4 MB
|
if (client->write_buffer_size > IPC_MAX_SIZE) {
|
||||||
sway_log(SWAY_ERROR, "Client write buffer too big (%zu), disconnecting client",
|
sway_log(SWAY_ERROR, "Client write buffer too big (%zu), disconnecting client",
|
||||||
client->write_buffer_size);
|
client->write_buffer_size);
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ void detect_proprietary(int allow_unsupported_gpu) {
|
||||||
|
|
||||||
void run_as_ipc_client(char *command, char *socket_path) {
|
void run_as_ipc_client(char *command, char *socket_path) {
|
||||||
int socketfd = ipc_open_socket(socket_path);
|
int socketfd = ipc_open_socket(socket_path);
|
||||||
uint32_t len = strlen(command);
|
size_t len = strlen(command);
|
||||||
char *resp = ipc_single_command(socketfd, IPC_COMMAND, command, &len);
|
char *resp = ipc_single_command(socketfd, IPC_COMMAND, command, &len);
|
||||||
printf("%s\n", resp);
|
printf("%s\n", resp == NULL ? "(null)" : resp);
|
||||||
free(resp);
|
free(resp);
|
||||||
close(socketfd);
|
close(socketfd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
|
void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
|
||||||
uint32_t size = strlen("workspace \"\"") + strlen(ws);
|
size_t size = strlen("workspace \"\"") + strlen(ws);
|
||||||
for (size_t i = 0; i < strlen(ws); ++i) {
|
for (size_t i = 0; i < strlen(ws); ++i) {
|
||||||
if (ws[i] == '"' || ws[i] == '\\') {
|
if (ws[i] == '"' || ws[i] == '\\') {
|
||||||
++size;
|
++size;
|
||||||
|
|
@ -343,9 +343,12 @@ bool ipc_get_workspaces(struct swaybar *bar) {
|
||||||
free_workspaces(&output->workspaces);
|
free_workspaces(&output->workspaces);
|
||||||
output->focused = false;
|
output->focused = false;
|
||||||
}
|
}
|
||||||
uint32_t len = 0;
|
size_t len = 0;
|
||||||
char *res = ipc_single_command(bar->ipc_socketfd,
|
char *res = ipc_single_command(bar->ipc_socketfd,
|
||||||
IPC_GET_WORKSPACES, NULL, &len);
|
IPC_GET_WORKSPACES, NULL, &len);
|
||||||
|
if (res == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
json_object *results = json_tokener_parse(res);
|
json_object *results = json_tokener_parse(res);
|
||||||
if (!results) {
|
if (!results) {
|
||||||
free(res);
|
free(res);
|
||||||
|
|
@ -411,16 +414,16 @@ bool ipc_get_workspaces(struct swaybar *bar) {
|
||||||
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
||||||
sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`",
|
sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`",
|
||||||
bind->button, bind->release, bind->command);
|
bind->button, bind->release, bind->command);
|
||||||
uint32_t len = strlen(bind->command);
|
size_t len = strlen(bind->command);
|
||||||
free(ipc_single_command(bar->ipc_socketfd,
|
free(ipc_single_command(bar->ipc_socketfd,
|
||||||
IPC_COMMAND, bind->command, &len));
|
IPC_COMMAND, bind->command, &len));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipc_initialize(struct swaybar *bar) {
|
bool ipc_initialize(struct swaybar *bar) {
|
||||||
uint32_t len = strlen(bar->id);
|
size_t len = strlen(bar->id);
|
||||||
char *res = ipc_single_command(bar->ipc_socketfd,
|
char *res = ipc_single_command(bar->ipc_socketfd,
|
||||||
IPC_GET_BAR_CONFIG, bar->id, &len);
|
IPC_GET_BAR_CONFIG, bar->id, &len);
|
||||||
if (!ipc_parse_config(bar->config, res)) {
|
if (res == NULL || !ipc_parse_config(bar->config, res)) {
|
||||||
free(res);
|
free(res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -550,8 +550,16 @@ int main(int argc, char **argv) {
|
||||||
int socketfd = ipc_open_socket(socket_path);
|
int socketfd = ipc_open_socket(socket_path);
|
||||||
struct timeval timeout = {.tv_sec = 3, .tv_usec = 0};
|
struct timeval timeout = {.tv_sec = 3, .tv_usec = 0};
|
||||||
ipc_set_recv_timeout(socketfd, timeout);
|
ipc_set_recv_timeout(socketfd, timeout);
|
||||||
uint32_t len = strlen(command);
|
size_t len = strlen(command);
|
||||||
char *resp = ipc_single_command(socketfd, type, command, &len);
|
char *resp = ipc_single_command(socketfd, type, command, &len);
|
||||||
|
if (resp == NULL) {
|
||||||
|
if (!quiet) {
|
||||||
|
sway_log(SWAY_ERROR, "Failed to receive reply");
|
||||||
|
}
|
||||||
|
close(socketfd);
|
||||||
|
free(socket_path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// pretty print the json
|
// pretty print the json
|
||||||
json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH);
|
json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue