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