ipc: use ipc_recv_message instead of duplicate code
This should fix the situation where i3 would read only the header and not the payload of the message.
This commit is contained in:
parent
dcb8ac84f8
commit
2478d0a2e0
70
src/ipc.c
70
src/ipc.c
|
@ -802,18 +802,16 @@ handler_t handlers[8] = {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
|
static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
|
||||||
char buf[2048];
|
uint32_t message_type;
|
||||||
int n = read(w->fd, buf, sizeof(buf));
|
uint32_t message_length;
|
||||||
|
uint8_t *message;
|
||||||
|
|
||||||
/* On error or an empty message, we close the connection */
|
int ret = ipc_recv_message(w->fd, &message_type, &message_length, &message);
|
||||||
if (n <= 0) {
|
/* EOF or other error */
|
||||||
#if 0
|
if (ret < 0) {
|
||||||
/* FIXME: I get these when closing a client socket,
|
/* Was this a spurious read? See ev(3) */
|
||||||
* therefore we just treat them as an error. Is this
|
if (ret == -1 && errno == EAGAIN)
|
||||||
* correct? */
|
return;
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If not, there was some kind of error. We don’t bother
|
/* If not, there was some kind of error. We don’t bother
|
||||||
* and close the connection */
|
* and close the connection */
|
||||||
|
@ -841,51 +839,11 @@ static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the message correctly */
|
if (message_type >= (sizeof(handlers) / sizeof(handler_t)))
|
||||||
buf[n] = '\0';
|
DLOG("Unhandled message type: %d\n", message_type);
|
||||||
|
else {
|
||||||
/* Check if the message starts with the i3 IPC magic code */
|
handler_t h = handlers[message_type];
|
||||||
if (n < strlen(I3_IPC_MAGIC)) {
|
h(w->fd, message, 0, message_length, message_type);
|
||||||
DLOG("IPC: message too short, ignoring\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(buf, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
|
|
||||||
DLOG("IPC: message does not start with the IPC magic\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *message = (uint8_t*)buf;
|
|
||||||
while (n > 0) {
|
|
||||||
DLOG("IPC: n = %d\n", n);
|
|
||||||
message += strlen(I3_IPC_MAGIC);
|
|
||||||
n -= strlen(I3_IPC_MAGIC);
|
|
||||||
|
|
||||||
/* The next 32 bit after the magic are the message size */
|
|
||||||
uint32_t message_size;
|
|
||||||
memcpy(&message_size, (uint32_t*)message, sizeof(uint32_t));
|
|
||||||
message += sizeof(uint32_t);
|
|
||||||
n -= sizeof(uint32_t);
|
|
||||||
|
|
||||||
if (message_size > n) {
|
|
||||||
DLOG("IPC: Either the message size was wrong or the message was not read completely, dropping\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The last 32 bits of the header are the message type */
|
|
||||||
uint32_t message_type;
|
|
||||||
memcpy(&message_type, (uint32_t*)message, sizeof(uint32_t));
|
|
||||||
message += sizeof(uint32_t);
|
|
||||||
n -= sizeof(uint32_t);
|
|
||||||
|
|
||||||
if (message_type >= (sizeof(handlers) / sizeof(handler_t)))
|
|
||||||
DLOG("Unhandled message type: %d\n", message_type);
|
|
||||||
else {
|
|
||||||
handler_t h = handlers[message_type];
|
|
||||||
h(w->fd, message, n, message_size, message_type);
|
|
||||||
}
|
|
||||||
n -= message_size;
|
|
||||||
message += message_size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue