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:
Michael Stapelberg 2013-01-23 18:59:36 +01:00
parent dcb8ac84f8
commit 2478d0a2e0
1 changed files with 14 additions and 56 deletions

View File

@ -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? */
if (errno == EAGAIN || errno == EWOULDBLOCK)
return; return;
#endif
/* If not, there was some kind of error. We dont bother /* If not, there was some kind of error. We dont 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 */
buf[n] = '\0';
/* Check if the message starts with the i3 IPC magic code */
if (n < strlen(I3_IPC_MAGIC)) {
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))) if (message_type >= (sizeof(handlers) / sizeof(handler_t)))
DLOG("Unhandled message type: %d\n", message_type); DLOG("Unhandled message type: %d\n", message_type);
else { else {
handler_t h = handlers[message_type]; handler_t h = handlers[message_type];
h(w->fd, message, n, message_size, message_type); h(w->fd, message, 0, message_length, message_type);
}
n -= message_size;
message += message_size;
} }
} }