2 * vim:ts=4:sw=4:expandtab
4 * i3 - an improved dynamic tiling window manager
5 * © 2009 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);
50 if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
51 ELOG("IPC: invalid magic in reply\n");
55 walk += strlen(I3_IPC_MAGIC);
56 memcpy(reply_length, walk, sizeof(uint32_t));
57 walk += sizeof(uint32_t);
58 if (message_type != NULL)
59 memcpy(message_type, walk, sizeof(uint32_t));
61 *reply = smalloc(*reply_length);
65 while (read_bytes < *reply_length) {
66 if ((n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes)) == -1) {
67 if (errno == EINTR || errno == EAGAIN)