]> git.sur5r.net Git - i3/i3/blob - libi3/ipc_send_message.c
05b1874799db0c76ed34756f96bafdc105906b89
[i3/i3] / libi3 / ipc_send_message.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  *
6  * © 2009-2011 Michael Stapelberg and contributors
7  *
8  * See file LICENSE for license information.
9  *
10  */
11 #include <string.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdint.h>
15 #include <err.h>
16
17 #include <i3/ipc.h>
18
19 #include "libi3.h"
20
21 /*
22  * Formats a message (payload) of the given size and type and sends it to i3 via
23  * the given socket file descriptor.
24  *
25  * Returns -1 when write() fails, errno will remain.
26  * Returns 0 on success.
27  *
28  */
29 int ipc_send_message(int sockfd, uint32_t message_size,
30                      uint32_t message_type, const uint8_t *payload) {
31     int buffer_size = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t) + message_size;
32     char msg[buffer_size];
33     char *walk = msg;
34
35     strncpy(walk, I3_IPC_MAGIC, buffer_size - 1);
36     walk += strlen(I3_IPC_MAGIC);
37     memcpy(walk, &message_size, sizeof(uint32_t));
38     walk += sizeof(uint32_t);
39     memcpy(walk, &message_type, sizeof(uint32_t));
40     walk += sizeof(uint32_t);
41     memcpy(walk, payload, message_size);
42
43     int sent_bytes = 0;
44     int bytes_to_go = buffer_size;
45     while (sent_bytes < bytes_to_go) {
46         int n = write(sockfd, msg + sent_bytes, bytes_to_go);
47         if (n == -1)
48             return -1;
49
50         sent_bytes += n;
51         bytes_to_go -= n;
52     }
53
54     return 0;
55 }