diff options
-rw-r--r-- | include/ipc.h | 6 | ||||
-rw-r--r-- | sway/ipc.c | 70 | ||||
-rw-r--r-- | sway/main.c | 3 |
3 files changed, 79 insertions, 0 deletions
diff --git a/include/ipc.h b/include/ipc.h new file mode 100644 index 00000000..aab9cf0c --- /dev/null +++ b/include/ipc.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _SWAY_IPC_H | ||
2 | #define _SWAY_IPC_H | ||
3 | |||
4 | void init_ipc(void); | ||
5 | |||
6 | #endif | ||
diff --git a/sway/ipc.c b/sway/ipc.c new file mode 100644 index 00000000..ac5246d2 --- /dev/null +++ b/sway/ipc.c | |||
@@ -0,0 +1,70 @@ | |||
1 | #include <errno.h> | ||
2 | #include <string.h> | ||
3 | #include <sys/socket.h> | ||
4 | #include <sys/un.h> | ||
5 | #include <wlc/wlc.h> | ||
6 | #include <unistd.h> | ||
7 | #include "log.h" | ||
8 | #include "config.h" | ||
9 | #include "commands.h" | ||
10 | |||
11 | static int ipc_socket = -1; | ||
12 | |||
13 | int ipc_handle_connection(int fd, uint32_t mask, void *data); | ||
14 | |||
15 | void init_ipc() { | ||
16 | ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); | ||
17 | if (ipc_socket == -1) { | ||
18 | sway_abort("Unable to create IPC socket"); | ||
19 | } | ||
20 | |||
21 | struct sockaddr_un ipc_sockaddr = { | ||
22 | .sun_family = AF_UNIX, | ||
23 | // TODO: use a proper socket path | ||
24 | .sun_path = "/tmp/sway.sock" | ||
25 | }; | ||
26 | |||
27 | unlink(ipc_sockaddr.sun_path); | ||
28 | if (bind(ipc_socket, (struct sockaddr *)&ipc_sockaddr, sizeof(ipc_sockaddr)) == -1) { | ||
29 | sway_abort("Unable to bind IPC socket"); | ||
30 | } | ||
31 | |||
32 | if (listen(ipc_socket, 3) == -1) { | ||
33 | sway_abort("Unable to listen on IPC socket"); | ||
34 | } | ||
35 | |||
36 | wlc_event_loop_add_fd(ipc_socket, WLC_EVENT_READABLE, ipc_handle_connection, NULL); | ||
37 | } | ||
38 | |||
39 | int ipc_handle_connection(int /*fd*/, uint32_t /*mask*/, void */*data*/) { | ||
40 | int client_socket = accept(ipc_socket, NULL, NULL); | ||
41 | if (client_socket == -1) { | ||
42 | char error[256]; | ||
43 | strerror_r(errno, error, sizeof(error)); | ||
44 | sway_log(L_INFO, "Unable to accept IPC client connection: %s", error); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | char buf[1024]; | ||
49 | if (recv(client_socket, buf, sizeof(buf), 0) == -1) { | ||
50 | char error[256]; | ||
51 | strerror_r(errno, error, sizeof(error)); | ||
52 | sway_log(L_INFO, "Unable to receive from IPC client: %s", error); | ||
53 | close(client_socket); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | sway_log(L_INFO, "Executing IPC command: %s", buf); | ||
58 | |||
59 | bool success = handle_command(config, buf); | ||
60 | snprintf(buf, sizeof(buf), "{\"success\":%s}\n", success ? "true" : "false"); | ||
61 | |||
62 | if (send(client_socket, buf, strlen(buf), 0) == -1) { | ||
63 | char error[256]; | ||
64 | strerror_r(errno, error, sizeof(error)); | ||
65 | sway_log(L_INFO, "Unable to send to IPC client: %s", error); | ||
66 | } | ||
67 | |||
68 | close(client_socket); | ||
69 | return 0; | ||
70 | } | ||
diff --git a/sway/main.c b/sway/main.c index 4a7e13c1..1af1278d 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "config.h" | 9 | #include "config.h" |
10 | #include "log.h" | 10 | #include "log.h" |
11 | #include "handlers.h" | 11 | #include "handlers.h" |
12 | #include "ipc.h" | ||
12 | 13 | ||
13 | static void sigchld_handle(int signal); | 14 | static void sigchld_handle(int signal); |
14 | 15 | ||
@@ -99,6 +100,8 @@ int main(int argc, char **argv) { | |||
99 | free(config_path); | 100 | free(config_path); |
100 | } | 101 | } |
101 | 102 | ||
103 | init_ipc(); | ||
104 | |||
102 | wlc_run(); | 105 | wlc_run(); |
103 | if (devnull) { | 106 | if (devnull) { |
104 | fclose(devnull); | 107 | fclose(devnull); |