Skip to content

Commit

Permalink
refactor: refactor: ipc
Browse files Browse the repository at this point in the history
  • Loading branch information
werererer committed Jan 13, 2024
1 parent d30b39e commit e355db9
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 215 deletions.
3 changes: 0 additions & 3 deletions include/ipc/ipc-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion include/ipc/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions include/ipc/ipc_server_sway_adapter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#ifndef IPC_SERVER_SWAY_ADAPTER_H
#define IPC_SERVER_SWAY_ADAPTER_H
#endif // IPC_SERVER_SWAY_ADAPTER_H
175 changes: 2 additions & 173 deletions src/ipc/ipc-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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/<user-id>"
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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
10 changes: 3 additions & 7 deletions src/ipc/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/ipc/ipc_server_sway_adapter.c
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
62 changes: 31 additions & 31 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,79 @@ 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',
'lib/lib_list2D.c',
'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'
Expand Down

0 comments on commit e355db9

Please sign in to comment.