aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ipc.h6
-rw-r--r--sway/ipc.c70
-rw-r--r--sway/main.c3
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 @@
+#ifndef _SWAY_IPC_H
+#define _SWAY_IPC_H
+
+void init_ipc(void);
+
+#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 @@
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <wlc/wlc.h>
+#include <unistd.h>
+#include "log.h"
+#include "config.h"
+#include "commands.h"
+
+static int ipc_socket = -1;
+
+int ipc_handle_connection(int fd, uint32_t mask, void *data);
+
+void init_ipc() {
+ ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ if (ipc_socket == -1) {
+ sway_abort("Unable to create IPC socket");
+ }
+
+ struct sockaddr_un ipc_sockaddr = {
+ .sun_family = AF_UNIX,
+ // TODO: use a proper socket path
+ .sun_path = "/tmp/sway.sock"
+ };
+
+ unlink(ipc_sockaddr.sun_path);
+ if (bind(ipc_socket, (struct sockaddr *)&ipc_sockaddr, sizeof(ipc_sockaddr)) == -1) {
+ sway_abort("Unable to bind IPC socket");
+ }
+
+ if (listen(ipc_socket, 3) == -1) {
+ sway_abort("Unable to listen on IPC socket");
+ }
+
+ wlc_event_loop_add_fd(ipc_socket, WLC_EVENT_READABLE, ipc_handle_connection, NULL);
+}
+
+int ipc_handle_connection(int /*fd*/, uint32_t /*mask*/, void */*data*/) {
+ int client_socket = accept(ipc_socket, NULL, NULL);
+ if (client_socket == -1) {
+ char error[256];
+ strerror_r(errno, error, sizeof(error));
+ sway_log(L_INFO, "Unable to accept IPC client connection: %s", error);
+ return 0;
+ }
+
+ char buf[1024];
+ if (recv(client_socket, buf, sizeof(buf), 0) == -1) {
+ char error[256];
+ strerror_r(errno, error, sizeof(error));
+ sway_log(L_INFO, "Unable to receive from IPC client: %s", error);
+ close(client_socket);
+ return 0;
+ }
+
+ sway_log(L_INFO, "Executing IPC command: %s", buf);
+
+ bool success = handle_command(config, buf);
+ snprintf(buf, sizeof(buf), "{\"success\":%s}\n", success ? "true" : "false");
+
+ if (send(client_socket, buf, strlen(buf), 0) == -1) {
+ char error[256];
+ strerror_r(errno, error, sizeof(error));
+ sway_log(L_INFO, "Unable to send to IPC client: %s", error);
+ }
+
+ close(client_socket);
+ return 0;
+}
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 @@
#include "config.h"
#include "log.h"
#include "handlers.h"
+#include "ipc.h"
static void sigchld_handle(int signal);
@@ -99,6 +100,8 @@ int main(int argc, char **argv) {
free(config_path);
}
+ init_ipc();
+
wlc_run();
if (devnull) {
fclose(devnull);