From 9afe0e6946b83293c68a2ab2c0f2beb57f5a0c24 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 19 Jun 2023 23:55:28 +0200 Subject: [PATCH] fixup! Add display server. --- display/connection.c | 16 ++-- display/display-code.c | 4 +- display/window.c | 8 +- libdisplay/include/display-protocol.h | 10 +-- libdisplay/include/display.h | 4 - libdisplay/libdisplay.c | 120 +++++++++++++------------- 6 files changed, 81 insertions(+), 81 deletions(-) diff --git a/display/connection.c b/display/connection.c index db745b4b..33dbd090 100644 --- a/display/connection.c +++ b/display/connection.c @@ -227,8 +227,8 @@ CONNECTION_MESSAGE_HANDLER_SERVER(chkblayout) event.error = errno; struct display_packet_header header; - header.message_id = EVENT_ACK; - header.message_length = sizeof(event); + header.id = EVENT_ACK; + header.size = sizeof(event); connection_schedule_transmit(connection, &header, sizeof(header)); connection_schedule_transmit(connection, &event, sizeof(event)); @@ -289,17 +289,17 @@ void connection_can_read(struct connection* connection, connection->packet_header_received += amount; } - size_t packet_length = connection->packet_header.message_length; + size_t packet_size = connection->packet_header.size; // TODO: Check allocation and protect against too big buffers. if ( !connection->packet ) - connection->packet = (unsigned char*) malloc(packet_length); + connection->packet = malloc(packet_size); - while ( connection->packet_received < packet_length ) + while ( connection->packet_received < packet_size ) { ssize_t amount = read(connection->fd, connection->packet + connection->packet_received, - packet_length - connection->packet_received); + packet_size - connection->packet_received); if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) return; if ( amount < 0 || amount == 0 ) @@ -307,14 +307,14 @@ void connection_can_read(struct connection* connection, connection->packet_received += amount; } - size_t packet_id = connection->packet_header.message_id; + size_t packet_id = connection->packet_header.id; if ( packet_id < num_connection_message_handlers ) { struct connection_message_handler_registration* handler = &connection_message_handlers[packet_id]; unsigned char* auxiliary = connection->packet + handler->message_size; - size_t auxiliary_size = packet_length - handler->message_size; + size_t auxiliary_size = packet_size - handler->message_size; handler->handler(connection, connection->packet, auxiliary, auxiliary_size, server); } diff --git a/display/display-code.c b/display/display-code.c index 23abaa2e..99447762 100644 --- a/display/display-code.c +++ b/display/display-code.c @@ -567,8 +567,8 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) event.codepoint = codepoint; struct display_packet_header header; - header.message_id = EVENT_KEYBOARD; - header.message_length = sizeof(event); + header.id = EVENT_KEYBOARD; + header.size = sizeof(event); assert(window->connection); diff --git a/display/window.c b/display/window.c index 3c31e6d8..c4d9e63d 100644 --- a/display/window.c +++ b/display/window.c @@ -308,8 +308,8 @@ void window_quit(struct window* window) event.window_id = window->window_id; struct display_packet_header header; - header.message_id = EVENT_QUIT; - header.message_length = sizeof(event); + header.id = EVENT_QUIT; + header.size = sizeof(event); assert(window->connection); @@ -550,8 +550,8 @@ void window_notify_client_resize(struct window* window) event.height = window_client_buffer(window).yres; struct display_packet_header header; - header.message_id = EVENT_RESIZE; - header.message_length = sizeof(event); + header.id = EVENT_RESIZE; + header.size = sizeof(event); assert(window->connection); diff --git a/libdisplay/include/display-protocol.h b/libdisplay/include/display-protocol.h index 4a185f8e..4d4185be 100644 --- a/libdisplay/include/display-protocol.h +++ b/libdisplay/include/display-protocol.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen. + * Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen. * Copyright (c) 2023 Juhani 'nortti' Krekelä. * * Permission to use, copy, modify, and distribute this software for any @@ -25,8 +25,8 @@ struct display_packet_header { - uint32_t message_id; - uint32_t message_length; + uint32_t id; + uint32_t size; }; #define DISPLAY_CREATE_WINDOW 0 @@ -64,7 +64,7 @@ struct display_render_window struct display_title_window { uint32_t window_id; - /* An UTF-8 string follows */ + /* A non-terminated UTF-8 string follows */ }; #define DISPLAY_SHOW_WINDOW 5 @@ -122,7 +122,7 @@ struct event_keyboard struct event_ack { uint32_t id; - int error; + int32_t error; }; #endif diff --git a/libdisplay/include/display.h b/libdisplay/include/display.h index 9d85f3f6..f2042318 100644 --- a/libdisplay/include/display.h +++ b/libdisplay/include/display.h @@ -36,11 +36,8 @@ int display_spawn(int argc, char** argv); struct display_connection* display_connect(const char* socket_path); struct display_connection* display_connect_default(void); void display_disconnect(struct display_connection* connection); - int display_connection_fd(struct display_connection* connection); - void display_shutdown(struct display_connection* connection, uint32_t code); - void display_create_window(struct display_connection* connection, uint32_t window_id); void display_destroy_window(struct display_connection* connection, @@ -63,7 +60,6 @@ void display_show_window(struct display_connection* connection, uint32_t window_id); void display_hide_window(struct display_connection* connection, uint32_t window_id); - void display_chkblayout(struct display_connection* connection, uint32_t id, void* data, diff --git a/libdisplay/libdisplay.c b/libdisplay/libdisplay.c index 69c72065..a8be68da 100644 --- a/libdisplay/libdisplay.c +++ b/libdisplay/libdisplay.c @@ -38,8 +38,10 @@ int display_spawn(int argc, char** argv) { - // TODO: Overflow. - char** new_argv = malloc((2 + argc + 1) * sizeof(char*)); + int length = 2 + 1; + if ( __builtin_add_overflow(length, argc, &length) ) + return errno = EOVERFLOW, -1; + char** new_argv = reallocarray(NULL, length, sizeof(char*)); if ( !new_argv ) return -1; new_argv[0] = (char*) "display"; @@ -58,7 +60,7 @@ static int open_local_client_socket(const char* path, int flags) { size_t path_length = strlen(path); size_t addr_size = offsetof(struct sockaddr_un, sun_path) + path_length + 1; - struct sockaddr_un* sockaddr = (struct sockaddr_un*) malloc(addr_size); + struct sockaddr_un* sockaddr = malloc(addr_size); if ( !sockaddr ) return -1; sockaddr->sun_family = AF_LOCAL; @@ -76,18 +78,17 @@ struct display_connection { int fd; struct display_packet_header header; - size_t header_bytes; + size_t header_got; uint8_t* payload; - size_t payload_bytes; + size_t payload_got; }; struct display_connection* display_connect(const char* socket_path) { struct display_connection* connection = - (struct display_connection*) malloc(sizeof(struct display_connection)); + calloc(1, sizeof(struct display_connection)); if ( !connection ) return NULL; - memset(connection, 0, sizeof(*connection)); if ( (connection->fd = open_local_client_socket(socket_path, 0)) < 0 ) return free(connection), (struct display_connection*) NULL; size_t send_buffer_size = 2 * 1024 * 1024; @@ -116,26 +117,26 @@ int display_connection_fd(struct display_connection* connection) } static void send_message(struct display_connection* connection, - uint32_t message_id, + uint32_t id, const void* message, size_t message_size, const void* auxiliary, size_t auxiliary_size) { struct display_packet_header header; - header.message_id = message_id; - header.message_length = message_size + auxiliary_size; + header.id = id; + header.size = message_size + auxiliary_size; writeall(connection->fd, &header, sizeof(header)); writeall(connection->fd, message, message_size); writeall(connection->fd, auxiliary, auxiliary_size); } static void send_message_no_aux(struct display_connection* connection, - uint32_t message_id, + uint32_t id, const void* message, size_t message_size) { - send_message(connection, message_id, message, message_size, 0, 0); + send_message(connection, id, message, message_size, 0, 0); } void display_shutdown(struct display_connection* connection, uint32_t code) @@ -197,7 +198,8 @@ void display_title_window(struct display_connection* connection, { struct display_title_window msg; msg.window_id = window_id; - send_message(connection, DISPLAY_TITLE_WINDOW, &msg, sizeof(msg), title, strlen(title)); + send_message(connection, DISPLAY_TITLE_WINDOW, &msg, sizeof(msg), title, + strlen(title)); } void display_show_window(struct display_connection* connection, @@ -229,41 +231,39 @@ void display_chkblayout(struct display_connection* connection, static bool display_read_event(struct display_connection* connection) { - while ( connection->header_bytes < sizeof(connection->header) ) + while ( connection->header_got < sizeof(connection->header) ) { errno = 0; - ssize_t amount = read(connection->fd, - (uint8_t*) &connection->header + connection->header_bytes, - sizeof(connection->header) - connection->header_bytes); + uint8_t* data = (uint8_t*) &connection->header + connection->header_got; + size_t left = sizeof(connection->header) - connection->header_got; + ssize_t amount = read(connection->fd, data, left); if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) break; - if ( amount < 0 ) - break; - if ( amount == 0 ) + if ( amount <= 0 ) return false; - connection->header_bytes += amount; + connection->header_got += amount; } - if ( connection->header_bytes == sizeof(connection->header) && + if ( connection->header_got == sizeof(connection->header) && !connection->payload ) { - connection->payload = (uint8_t*) malloc(connection->header.message_length); - connection->payload_bytes = 0; + connection->payload = malloc(connection->header.size); + if ( !connection->payload ) + return false; + connection->payload_got = 0; } - while ( connection->header_bytes == sizeof(connection->header) && + while ( connection->header_got == sizeof(connection->header) && connection->payload && - connection->payload_bytes < connection->header.message_length ) + connection->payload_got < connection->header.size ) { errno = 0; - ssize_t amount = read(connection->fd, - connection->payload + connection->payload_bytes, - connection->header.message_length - connection->payload_bytes); + uint8_t* data = connection->payload + connection->payload_got; + size_t left = connection->header.size - connection->payload_got; + ssize_t amount = read(connection->fd, data, left); if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) break; - if ( amount < 0 ) - break; - if ( amount == 0 ) + if ( amount <= 0 ) return false; - connection->payload_bytes += amount; + connection->payload_got += amount; } return true; @@ -272,16 +272,16 @@ static bool display_read_event(struct display_connection* connection) static int display_dispatch_event(struct display_connection* connection, struct display_event_handlers* handlers) { - if ( connection->header_bytes == sizeof(connection->header) && + if ( connection->header_got == sizeof(connection->header) && connection->payload && - connection->payload_bytes == connection->header.message_length ) + connection->payload_got == connection->header.size ) { - // TODO: == instead of <= due to warning. Maybe all should be changed to - // use == instead. - if ( connection->header.message_id == EVENT_DISCONNECT && - connection->header.message_length ==/*>=*/ sizeof(struct event_disconnect) ) + void* payload = connection->payload; + + if ( connection->header.id == EVENT_DISCONNECT && + connection->header.size == sizeof(struct event_disconnect) ) { - struct event_disconnect* event = (struct event_disconnect*) connection->payload; + struct event_disconnect* event = payload; (void) event; if ( handlers->disconnect_handler ) handlers->disconnect_handler(handlers->context); @@ -289,43 +289,47 @@ static int display_dispatch_event(struct display_connection* connection, exit(0); } - if ( connection->header.message_id == EVENT_QUIT && - connection->header.message_length >= sizeof(struct event_quit) ) + if ( connection->header.id == EVENT_QUIT && + connection->header.size == sizeof(struct event_quit) ) { - struct event_quit* event = (struct event_quit*) connection->payload; + struct event_quit* event = payload; if ( handlers->quit_handler ) handlers->quit_handler(handlers->context, event->window_id); else exit(0); } - if ( connection->header.message_id == EVENT_RESIZE && - connection->header.message_length >= sizeof(struct event_resize) ) + if ( connection->header.id == EVENT_RESIZE && + connection->header.size == sizeof(struct event_resize) ) { - struct event_resize* event = (struct event_resize*) connection->payload; + struct event_resize* event = payload; if ( handlers->resize_handler ) - handlers->resize_handler(handlers->context, event->window_id, event->width, event->height); + handlers->resize_handler(handlers->context, event->window_id, + event->width, event->height); } - if ( connection->header.message_id == EVENT_KEYBOARD && - connection->header.message_length >= sizeof(struct event_keyboard) ) + if ( connection->header.id == EVENT_KEYBOARD && + connection->header.size == sizeof(struct event_keyboard) ) { - struct event_keyboard* event = (struct event_keyboard*) connection->payload; + struct event_keyboard* event = payload; if ( handlers->keyboard_handler ) - handlers->keyboard_handler(handlers->context, event->window_id, event->codepoint); + handlers->keyboard_handler(handlers->context, event->window_id, + event->codepoint); } - if ( connection->header.message_id == EVENT_ACK && - connection->header.message_length >= sizeof(struct event_ack) ) + if ( connection->header.id == EVENT_ACK && + connection->header.size == sizeof(struct event_ack) ) { - struct event_ack* event = (struct event_ack*) connection->payload; + struct event_ack* event = payload; if ( handlers->ack_handler ) - handlers->ack_handler(handlers->context, event->id, event->error); + handlers->ack_handler(handlers->context, event->id, + event->error); } - connection->header_bytes = 0; - free(connection->payload), connection->payload = NULL; - connection->payload_bytes = 0; + connection->header_got = 0; + free(connection->payload); + connection->payload = NULL; + connection->payload_got = 0; return 0; }