+static void ipc_recv_message(int sockfd, uint32_t message_type,
+ uint32_t *reply_length, uint8_t **reply) {
+ /* Read the message header first */
+ uint32_t to_read = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t);
+ char msg[to_read];
+ char *walk = msg;
+
+ uint32_t read_bytes = 0;
+ while (read_bytes < to_read) {
+ int n = read(sockfd, msg + read_bytes, to_read);
+ if (n == -1)
+ err(EXIT_FAILURE, "read() failed");
+
+ read_bytes += n;
+ to_read -= n;
+ }
+
+ if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0)
+ errx(EXIT_FAILURE, "invalid magic in reply");
+
+ walk += strlen(I3_IPC_MAGIC);
+ *reply_length = *((uint32_t*)walk);
+ walk += sizeof(uint32_t);
+ if (*((uint32_t*)walk) != message_type)
+ errx(EXIT_FAILURE, "unexpected reply type (got %d, expected %d)", *((uint32_t*)walk), message_type);
+ walk += sizeof(uint32_t);
+
+ *reply = malloc(*reply_length);
+ if ((*reply) == NULL)
+ err(EXIT_FAILURE, "malloc() failed");
+
+ to_read = *reply_length;
+ read_bytes = 0;
+ while (read_bytes < to_read) {
+ int n = read(sockfd, *reply + read_bytes, to_read);
+ if (n == -1)
+ err(EXIT_FAILURE, "read() failed");
+
+ read_bytes += n;
+ to_read -= n;
+ }
+}
+