2 * vim:ts=4:sw=4:expandtab
4 * i3 - an improved dynamic tiling window manager
5 * © 2009-2013 Michael Stapelberg and contributors (see also: LICENSE)
20 * Reads a message from the given socket file descriptor and stores its length
21 * (reply_length) as well as a pointer to its contents (reply).
23 * Returns -1 when read() fails, errno will remain.
25 * Returns -3 when the IPC protocol is violated (invalid magic, unexpected
26 * message type, EOF instead of a message). Additionally, the error will be
28 * Returns 0 on success.
31 int ipc_recv_message(int sockfd, uint32_t *message_type,
32 uint32_t *reply_length, uint8_t **reply) {
33 /* Read the message header first */
34 const uint32_t to_read = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t);
38 uint32_t read_bytes = 0;
39 while (read_bytes < to_read) {
40 int n = read(sockfd, msg + read_bytes, to_read - read_bytes);
44 ELOG("IPC: received EOF instead of reply\n");
51 if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
52 ELOG("IPC: invalid magic in reply\n");
56 walk += strlen(I3_IPC_MAGIC);
57 memcpy(reply_length, walk, sizeof(uint32_t));
58 walk += sizeof(uint32_t);
59 if (message_type != NULL)
60 memcpy(message_type, walk, sizeof(uint32_t));
62 *reply = smalloc(*reply_length);
66 while (read_bytes < *reply_length) {
67 if ((n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes)) == -1) {
68 if (errno == EINTR || errno == EAGAIN)