From e355db90ed443ea777839e04dcab668326d373e1 Mon Sep 17 00:00:00 2001 From: Jakob Schlanstedt Date: Sat, 13 Jan 2024 15:15:38 +0100 Subject: [PATCH] refactor: refactor: ipc --- include/ipc/ipc-server.h | 3 - include/ipc/ipc.h | 7 +- include/ipc/ipc_server_sway_adapter.h | 3 + src/ipc/ipc-server.c | 175 +------------------------- src/ipc/ipc.c | 10 +- src/ipc/ipc_server_sway_adapter.c | 2 + src/meson.build | 62 ++++----- 7 files changed, 47 insertions(+), 215 deletions(-) diff --git a/include/ipc/ipc-server.h b/include/ipc/ipc-server.h index a943c455..daaa29ea 100644 --- a/include/ipc/ipc-server.h +++ b/include/ipc/ipc-server.h @@ -5,12 +5,9 @@ #include "ipc/ipc.h" -void ipc_init(struct wl_event_loop *wl_event_loop); bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type, const char *payload, uint32_t payload_length); -struct sockaddr_un *ipc_user_sockaddr(void); - void ipc_event_tag(); void ipc_event_window(); int handle_client_payload(struct ipc_client *client); diff --git a/include/ipc/ipc.h b/include/ipc/ipc.h index 02c224c8..33cf5222 100644 --- a/include/ipc/ipc.h +++ b/include/ipc/ipc.h @@ -43,12 +43,17 @@ struct ipc_client { enum ipc_command_type pending_type; }; - +void ipc_init(struct wl_event_loop *wl_event_loop); int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data); int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data); bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_type, const char *payload, uint32_t payload_length); void ipc_send_event(const char *json_string, enum ipc_command_type event); +int ipc_handle_connection(int fd, uint32_t mask, void *data); +void ipc_client_disconnect(struct ipc_client *client); + +struct sockaddr_un *ipc_user_sockaddr(void); + #endif // IPC_H diff --git a/include/ipc/ipc_server_sway_adapter.h b/include/ipc/ipc_server_sway_adapter.h index e69de29b..c3d9ce01 100644 --- a/include/ipc/ipc_server_sway_adapter.h +++ b/include/ipc/ipc_server_sway_adapter.h @@ -0,0 +1,3 @@ +#ifndef IPC_SERVER_SWAY_ADAPTER_H +#define IPC_SERVER_SWAY_ADAPTER_H +#endif // IPC_SERVER_SWAY_ADAPTER_H diff --git a/src/ipc/ipc-server.c b/src/ipc/ipc-server.c index 2fb255bd..452d88a3 100644 --- a/src/ipc/ipc-server.c +++ b/src/ipc/ipc-server.c @@ -26,121 +26,11 @@ #include "command.h" #include "monitor.h" -static int ipc_socket = -1; -static struct sockaddr_un *ipc_sockaddr = NULL; -static GPtrArray *ipc_client_list; - // Macro to generate a bitmask for an event. // It shifts 1 to the left by the lower 7 bits of the event value. -struct sockaddr_un *ipc_user_sockaddr(void); -int ipc_handle_connection(int fd, uint32_t mask, void *data); -int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data); -void ipc_client_disconnect(struct ipc_client *client); void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_length, enum ipc_command_type payload_type); -void ipc_init(struct wl_event_loop *wl_event_loop) { - ipc_socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (ipc_socket == -1) { - printf("Unable to create IPC socket\n"); - } - if (fcntl(ipc_socket, F_SETFD, FD_CLOEXEC) == -1) { - printf("Unable to set CLOEXEC on IPC socket\n"); - } - if (fcntl(ipc_socket, F_SETFL, O_NONBLOCK) == -1) { - printf("Unable to set NONBLOCK on IPC socket\n"); - } - - ipc_sockaddr = ipc_user_sockaddr(); - - unlink(ipc_sockaddr->sun_path); - if (bind(ipc_socket, (struct sockaddr *)ipc_sockaddr, sizeof(*ipc_sockaddr)) == -1) { - printf("Unable to bind IPC socket\n"); - } - - if (listen(ipc_socket, 3) == -1) { - printf("Unable to listen on IPC socket\n"); - } - - // Set SWAY IPC socket path so that waybar automatically shows - // tags(tags) - setenv("SWAYSOCK", ipc_sockaddr->sun_path, 1); - setenv("JAPOKWMSOCK", ipc_sockaddr->sun_path, 1); - - ipc_client_list = g_ptr_array_new(); - - wl_event_loop_add_fd(wl_event_loop, ipc_socket, - WL_EVENT_READABLE, ipc_handle_connection, wl_event_loop); -} - -struct sockaddr_un *ipc_user_sockaddr(void) { - struct sockaddr_un *ipc_sockaddr = malloc(sizeof(struct sockaddr_un)); - if (ipc_sockaddr == NULL) { - printf("Can't allocate ipc_sockaddr\n"); - } - - ipc_sockaddr->sun_family = AF_UNIX; - int path_size = sizeof(ipc_sockaddr->sun_path); - - // Env var typically set by logind, e.g. "/run/user/" - const char *dir = getenv("XDG_RUNTIME_DIR"); - if (!dir) { - dir = "/tmp"; - } - if (path_size <= snprintf(ipc_sockaddr->sun_path, path_size, - "%s/japokwm-ipc.%u.%i.sock", dir, getuid(), getpid())) { - printf("Socket path won't fit into ipc_sockaddr->sun_path\n"); - } - - return ipc_sockaddr; -} - -int ipc_handle_connection(int fd, uint32_t mask, void *data) { - struct wl_event_loop *wl_event_loop = data; - (void) fd; - int client_fd = accept(ipc_socket, NULL, NULL); - if (client_fd == -1) { - printf("Unable to accept IPC client connection\n"); - return 0; - } - - if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) == -1) { - printf("Unable to set CLOEXEC on IPC client socket\n"); - close(client_fd); - return 0; - } - if (fcntl(client_fd, F_SETFL, O_NONBLOCK) == -1) { - printf("Unable to set NONBLOCK on IPC client socket\n"); - close(client_fd); - return 0; - } - - struct ipc_client *client = malloc(sizeof(struct ipc_client)); - if (!client) { - printf("Unable to allocate ipc client\n"); - close(client_fd); - return 0; - } - client->pending_length = 0; - client->fd = client_fd; - client->subscribed_events = 0; - client->event_source = wl_event_loop_add_fd(wl_event_loop, - client_fd, WL_EVENT_READABLE, ipc_client_handle_readable, client); - client->writable_event_source = NULL; - - client->write_buffer_size = 128; - client->write_buffer_len = 0; - client->write_buffer = malloc(client->write_buffer_size); - if (!client->write_buffer) { - printf("Unable to allocate ipc client write buffer\n"); - close(client_fd); - return 0; - } - - g_ptr_array_add(ipc_client_list, client); - return 0; -} - // Forward declaration of helper functions static int read_client_header(int client_fd, struct ipc_client *client); static int get_available_read_data(int client_fd, struct ipc_client *client); @@ -180,7 +70,8 @@ static int read_client_header(int client_fd, struct ipc_client *client) { return handle_client_payload(client); } -int handle_client_payload(struct ipc_client *client) { +int handle_client_payload(struct ipc_client *client) +{ if (client->pending_length <= 0) { return 0; } @@ -209,68 +100,6 @@ void ipc_event_tag() { } } -int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { - struct ipc_client *client = data; - - if (mask & WL_EVENT_ERROR) { - printf("IPC Client socket error, removing client\n"); - ipc_client_disconnect(client); - return 0; - } - - if (mask & WL_EVENT_HANGUP) { - printf("Client %d hung up\n", client->fd); - ipc_client_disconnect(client); - return 0; - } - - if (client->write_buffer_len <= 0) { - return 0; - } - - ssize_t written = write(client->fd, client->write_buffer, client->write_buffer_len); - - if (written == -1 && errno == EAGAIN) { - return 0; - } else if (written == -1) { - printf("Unable to send data from queue to IPC client\n"); - ipc_client_disconnect(client); - return 0; - } - - memmove(client->write_buffer, client->write_buffer + written, client->write_buffer_len - written); - client->write_buffer_len -= written; - - if (client->write_buffer_len == 0 && client->writable_event_source) { - wl_event_source_remove(client->writable_event_source); - client->writable_event_source = NULL; - } - - return 0; -} - -void ipc_client_disconnect(struct ipc_client *client) { - if (!(client != NULL)) { - return; - } - - shutdown(client->fd, SHUT_RDWR); - - printf("IPC Client %d disconnected\n", client->fd); - wl_event_source_remove(client->event_source); - if (client->writable_event_source) { - wl_event_source_remove(client->writable_event_source); - } - size_t i = 0; - while (i < ipc_client_list->len && g_ptr_array_index(ipc_client_list, i) != client) { - i++; - } - g_ptr_array_remove_index(ipc_client_list, i); - free(client->write_buffer); - close(client->fd); - free(client); -} - void ipc_event_window() { ipc_send_event("", IPC_EVENT_WINDOW); } diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 466308bb..63934d00 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -21,14 +21,9 @@ static struct sockaddr_un *ipc_sockaddr = NULL; static GPtrArray *ipc_client_list; static int read_client_header(int client_fd, struct ipc_client *client); -static void ipc_client_disconnect(struct ipc_client *client); static int check_socket_errors(uint32_t mask, struct ipc_client *client); static int get_available_read_data(int client_fd, struct ipc_client *client); -struct sockaddr_un *ipc_user_sockaddr(void); - -int ipc_handle_connection(int fd, uint32_t mask, void *data); - void ipc_init(struct wl_event_loop *wl_event_loop) { int ipc_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (ipc_socket == -1) { @@ -63,7 +58,8 @@ void ipc_init(struct wl_event_loop *wl_event_loop) { WL_EVENT_READABLE, ipc_handle_connection, wl_event_loop); } -int ipc_handle_connection(int fd, uint32_t mask, void *data) { +int ipc_handle_connection(int fd, uint32_t mask, void *data) +{ struct wl_event_loop *wl_event_loop = data; (void) fd; int ipc_socket = server.ipc_socket; @@ -134,7 +130,7 @@ struct sockaddr_un *ipc_user_sockaddr(void) { return ipc_sockaddr; } -static void ipc_client_disconnect(struct ipc_client *client) { +void ipc_client_disconnect(struct ipc_client *client) { if (!(client != NULL)) { return; } diff --git a/src/ipc/ipc_server_sway_adapter.c b/src/ipc/ipc_server_sway_adapter.c index 8c077e12..45ba0aee 100644 --- a/src/ipc/ipc_server_sway_adapter.c +++ b/src/ipc/ipc_server_sway_adapter.c @@ -1,3 +1,5 @@ +#include "ipc/ipc_server_sway_adapter.h" + // See https://i3wm.org/docs/ipc.html for protocol information // TODO: properly implement the adapter[:w // #include "json_object.h" diff --git a/src/meson.build b/src/meson.build index e9f227ed..9e7f3a32 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,38 +14,47 @@ deps += [luaDep] main = files('main.c') srcs = files( - 'bitset/bitset.c', 'client.c', 'color.c', 'command.c', - 'command/commands.c', 'container.c', + 'subsurface.c', 'cursor.c', - 'error_handling.c', 'event_handler.c', 'input_manager.c', - 'ipc/ipc-json.c', - 'ipc/ipc-server.c', - 'ipc/ipc.c', - 'ipc/ipc_server_sway_adapter.c', 'keybinding.c', 'keyboard.c', + 'tablet.c', 'layer_shell.c', 'layout.c', + 'main.c', + 'monitor.c', + 'options.c', + 'output.c', + 'popup.c', + 'root.c', + 'scratchpad.c', + 'seat.c', + 'server.c', + 'tagset.c', + 'translationLayer.c', + 'wlr_signal.c', + 'tag.c', + 'xdg_shell.c', + 'xwayland.c', + 'bitset/bitset.c', + 'command/commands.c', 'lib/lib_action.c', 'lib/lib_bitset.c', 'lib/lib_color.c', + 'lib/lib_gmp.c', 'lib/lib_container.c', - 'lib/lib_container_list.c', - 'lib/lib_container_property.c', - 'lib/lib_container_property_list.c', 'lib/lib_cursor.c', 'lib/lib_cursor_mode.c', 'lib/lib_direction.c', 'lib/lib_event_handler.c', 'lib/lib_focus_set.c', 'lib/lib_geom.c', - 'lib/lib_gmp.c', 'lib/lib_info.c', 'lib/lib_layout.c', 'lib/lib_list.c', @@ -53,40 +62,31 @@ srcs = files( 'lib/lib_monitor.c', 'lib/lib_options.c', 'lib/lib_output_transform.c', - 'lib/lib_ring_buffer.c', - 'lib/lib_root.c', 'lib/lib_server.c', + 'lib/lib_root.c', 'lib/lib_tag.c', + 'lib/lib_container_property.c', + 'lib/lib_container_list.c', + 'lib/lib_container_property_list.c', + 'ring_buffer.c', + 'lib/lib_ring_buffer.c', 'list_sets/container_stack_set.c', 'list_sets/focus_stack_set.c', 'list_sets/list_set.c', - 'main.c', - 'monitor.c', - 'options.c', - 'output.c', - 'popup.c', 'render.c', - 'ring_buffer.c', - 'root.c', 'rules/mon_rule.c', 'rules/rule.c', - 'scratchpad.c', - 'seat.c', - 'server.c', - 'subsurface.c', - 'tablet.c', - 'tag.c', - 'tagset.c', 'tile/tileUtils.c', - 'translationLayer.c', 'utils/coreUtils.c', 'utils/gapUtils.c', 'utils/parseConfigUtils.c', 'utils/stringUtils.c', 'utils/writeFile.c', - 'wlr_signal.c', - 'xdg_shell.c', - 'xwayland.c', + 'ipc/ipc_server_sway_adapter.c', + 'ipc/ipc-json.c', + 'ipc/ipc-server.c', + 'ipc/ipc.c', + 'error_handling.c', ) libName = 'japokwm_lib'