Add type to returned response.

Makes `ipc_recv_response` return a struct with size, type and payload
rather than just the payload string.

This is useful if the type has to be checked on the client.
master
Mikkel Oscar Lyderik 10 years ago
parent 19833fbc8b
commit 7298a9c67a

@ -10,6 +10,7 @@
#include "stringop.h" #include "stringop.h"
#include "ipc.h" #include "ipc.h"
#include "readline.h" #include "readline.h"
#include "ipc-client.h"
static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
static const size_t ipc_header_size = sizeof(ipc_magic)+8; static const size_t ipc_header_size = sizeof(ipc_magic)+8;
@ -39,7 +40,7 @@ int ipc_open_socket(const char *socket_path) {
return socketfd; return socketfd;
} }
char *ipc_recv_response(int socketfd, uint32_t *len) { struct ipc_response *ipc_recv_response(int socketfd) {
char data[ipc_header_size]; char data[ipc_header_size];
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
@ -52,21 +53,29 @@ char *ipc_recv_response(int socketfd, uint32_t *len) {
total += received; total += received;
} }
struct ipc_response *response = malloc(sizeof(struct ipc_response));
total = 0; total = 0;
*len = data32[0]; response->size = data32[0];
char *response = malloc(*len + 1); response->type = data32[1];
while (total < *len) { char *payload = malloc(response->size + 1);
ssize_t received = recv(socketfd, response + total, *len - total, 0); while (total < response->size) {
ssize_t received = recv(socketfd, payload + total, response->size - total, 0);
if (received < 0) { if (received < 0) {
sway_abort("Unable to receive IPC response"); sway_abort("Unable to receive IPC response");
} }
total += received; total += received;
} }
response[*len] = '\0'; payload[response->size] = '\0';
response->payload = payload;
return response; return response;
} }
void free_ipc_response(struct ipc_response *response) {
free(response->payload);
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, uint32_t *len) {
char data[ipc_header_size]; char data[ipc_header_size];
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
@ -82,5 +91,10 @@ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint3
sway_abort("Unable to send IPC payload"); sway_abort("Unable to send IPC payload");
} }
return ipc_recv_response(socketfd, len); struct ipc_response *resp = ipc_recv_response(socketfd);
char *response = resp->payload;
*len = resp->size;
free(resp);
return response;
} }

@ -3,6 +3,16 @@
#include "ipc.h" #include "ipc.h"
/**
* IPC response including type of IPC response, size of payload and the json
* encoded payload string.
*/
struct ipc_response {
uint32_t size;
uint32_t type;
char *payload;
};
/** /**
* Gets the path to the IPC socket from sway. * Gets the path to the IPC socket from sway.
*/ */
@ -17,9 +27,12 @@ int ipc_open_socket(const char *socket_path);
*/ */
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, uint32_t *len);
/** /**
* Receives a single IPC resposne and returns the buffer. len will be updated * Receives a single IPC response and returns an ipc_response.
* with the length of the buffer returned from sway. */
struct ipc_response *ipc_recv_response(int socketfd);
/**
* Free ipc_response struct
*/ */
char *ipc_recv_response(int socketfd, uint32_t *len); void free_ipc_response(struct ipc_response *response);
#endif #endif

@ -1025,9 +1025,8 @@ void poll_for_update() {
if (FD_ISSET(ipc_event_socketfd, &readfds)) { if (FD_ISSET(ipc_event_socketfd, &readfds)) {
sway_log(L_DEBUG, "Got workspace update."); sway_log(L_DEBUG, "Got workspace update.");
uint32_t len; struct ipc_response *resp = ipc_recv_response(ipc_event_socketfd);
char *buf = ipc_recv_response(ipc_event_socketfd, &len); free_ipc_response(resp);
free(buf);
ipc_update_workspaces(); ipc_update_workspaces();
dirty = true; dirty = true;
} }

Loading…
Cancel
Save