fixup! Add display server.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-06-17 22:01:26 +02:00
parent 684a141953
commit eb9fb7b0fc
5 changed files with 64 additions and 50 deletions

View File

@ -42,18 +42,21 @@ void connection_schedule_transmit(struct connection* connection,
size_t available = connection->outgoing_size - connection->outgoing_used; size_t available = connection->outgoing_size - connection->outgoing_used;
if ( available < count ) if ( available < count )
{ {
// TODO: Overflow.
size_t required_size = connection->outgoing_used + count; size_t required_size = connection->outgoing_used + count;
unsigned char* new_outgoing = (unsigned char*) malloc(required_size); // TODO: Check allocation.
size_t first_part_available = connection->outgoing_size - connection->outgoing_offset; unsigned char* new_outgoing = malloc(required_size);
size_t first_part = connection->outgoing_used < first_part_available ? size_t first_available =
connection->outgoing_used : connection->outgoing_size - connection->outgoing_offset;
first_part_available; size_t first = connection->outgoing_used < first_available ?
connection->outgoing_used :
first_available;
if ( connection->outgoing ) if ( connection->outgoing )
{ {
memcpy(new_outgoing, connection->outgoing + memcpy(new_outgoing, connection->outgoing +
connection->outgoing_offset, first_part); connection->outgoing_offset, first);
size_t second_part = connection->outgoing_used - first_part; size_t second = connection->outgoing_used - first;
memcpy(new_outgoing + first_part, connection->outgoing, second_part); memcpy(new_outgoing + first, connection->outgoing, second);
free(connection->outgoing); free(connection->outgoing);
} }
connection->outgoing_offset = 0; connection->outgoing_offset = 0;
@ -61,12 +64,14 @@ void connection_schedule_transmit(struct connection* connection,
connection->outgoing = new_outgoing; connection->outgoing = new_outgoing;
} }
size_t used_offset = (connection->outgoing_offset + connection->outgoing_used) % connection->outgoing_size; size_t used_offset =
size_t first_part_available = connection->outgoing_size - used_offset; (connection->outgoing_offset + connection->outgoing_used) %
size_t first_part = count < first_part_available ? count : first_part_available; connection->outgoing_size;
memcpy(connection->outgoing + used_offset, buffer, first_part); size_t first_available = connection->outgoing_size - used_offset;
size_t second_part = count - first_part; size_t first = count < first_available ? count : first_available;
memcpy(connection->outgoing, (const unsigned char*) buffer + first_part, second_part); memcpy(connection->outgoing + used_offset, buffer, first);
size_t second = count - first;
memcpy(connection->outgoing, (const unsigned char*) buffer + first, second);
connection->outgoing_used += count; connection->outgoing_used += count;
} }
@ -97,25 +102,28 @@ struct window* connection_find_window(struct connection* connection,
} }
#define CONNECTION_MESSAGE_HANDLER_NO_AUX(message_name) \ #define CONNECTION_MESSAGE_HANDLER_NO_AUX(message_name) \
void connection_handler_##message_name(struct connection* connection, \ void connection_handler_##message_name( \
struct display_##message_name* msg, \ struct connection* connection, \
void* auxiliary __attribute__((unused)), \ struct display_##message_name* msg, \
size_t auxiliary_size __attribute__((unused)), \ void* auxiliary __attribute__((unused)), \
const struct server* server __attribute__((unused))) size_t auxiliary_size __attribute__((unused)), \
const struct server* server __attribute__((unused)))
#define CONNECTION_MESSAGE_HANDLER(message_name) \ #define CONNECTION_MESSAGE_HANDLER(message_name) \
void connection_handler_##message_name(struct connection* connection, \ void connection_handler_##message_name( \
struct display_##message_name* msg, \ struct connection* connection, \
unsigned char* auxiliary, \ struct display_##message_name* msg, \
size_t auxiliary_size, \ unsigned char* auxiliary, \
const struct server* server __attribute__((unused))) size_t auxiliary_size, \
const struct server* server __attribute__((unused)))
#define CONNECTION_MESSAGE_HANDLER_SERVER(message_name) \ #define CONNECTION_MESSAGE_HANDLER_SERVER(message_name) \
void connection_handler_##message_name(struct connection* connection, \ void connection_handler_##message_name( \
struct display_##message_name* msg, \ struct connection* connection, \
unsigned char* auxiliary, \ struct display_##message_name* msg, \
size_t auxiliary_size, \ unsigned char* auxiliary, \
const struct server* server) size_t auxiliary_size, \
const struct server* server)
CONNECTION_MESSAGE_HANDLER_NO_AUX(shutdown) CONNECTION_MESSAGE_HANDLER_NO_AUX(shutdown)
{ {
@ -134,7 +142,8 @@ CONNECTION_MESSAGE_HANDLER_NO_AUX(shutdown)
CONNECTION_MESSAGE_HANDLER_NO_AUX(create_window) CONNECTION_MESSAGE_HANDLER_NO_AUX(create_window)
{ {
struct window* window = connection_find_window_raw(connection, msg->window_id); struct window* window =
connection_find_window_raw(connection, msg->window_id);
if ( !window ) if ( !window )
return; return;
if ( window->created ) if ( window->created )
@ -265,7 +274,8 @@ short connection_interested_poll_events(struct connection* connection)
void connection_can_read(struct connection* connection, void connection_can_read(struct connection* connection,
const struct server* server) const struct server* server)
{ {
while ( connection->packet_header_received < sizeof(connection->packet_header) ) while ( connection->packet_header_received <
sizeof(connection->packet_header) )
{ {
ssize_t amount = read(connection->fd, ssize_t amount = read(connection->fd,
(unsigned char*) &connection->packet_header + (unsigned char*) &connection->packet_header +
@ -275,12 +285,13 @@ void connection_can_read(struct connection* connection,
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
return; return;
if ( amount < 0 || amount == 0 ) if ( amount < 0 || amount == 0 )
return; // TODO: No longer signal interest in reading and disconnect. return; // TODO: No longer signal interest in reading + disconnect.
connection->packet_header_received += amount; connection->packet_header_received += amount;
} }
size_t packet_length = connection->packet_header.message_length; size_t packet_length = connection->packet_header.message_length;
// TODO: Check allocation and protect against too big buffers.
if ( !connection->packet ) if ( !connection->packet )
connection->packet = (unsigned char*) malloc(packet_length); connection->packet = (unsigned char*) malloc(packet_length);
@ -292,7 +303,7 @@ void connection_can_read(struct connection* connection,
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
return; return;
if ( amount < 0 || amount == 0 ) if ( amount < 0 || amount == 0 )
return; // TODO: No longer signal interest in reading and disconnect. return; // TODO: No longer signal interest in reading + disconnect.
connection->packet_received += amount; connection->packet_received += amount;
} }
@ -313,7 +324,7 @@ void connection_can_read(struct connection* connection,
connection->packet = NULL; connection->packet = NULL;
connection->packet_received = 0; connection->packet_received = 0;
// TODO: Check if we can received another packet, but only if we haven't // TODO: Check if we can receive another packet, but only if we haven't
// done so much work that the display server is starved. // done so much work that the display server is starved.
} }
@ -321,14 +332,18 @@ void connection_can_write(struct connection* connection)
{ {
while ( connection->outgoing_used ) while ( connection->outgoing_used )
{ {
size_t available = connection->outgoing_size - connection->outgoing_offset; size_t available =
size_t count = connection->outgoing_used < available ? connection->outgoing_used : available; connection->outgoing_size - connection->outgoing_offset;
ssize_t amount = write(connection->fd, connection->outgoing + connection->outgoing_offset, count); size_t count = connection->outgoing_used < available ?
connection->outgoing_used : available;
unsigned char* buf = connection->outgoing + connection->outgoing_offset;
ssize_t amount = write(connection->fd, buf, count);
if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) ) if ( amount < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) )
return; return;
if ( amount < 0 || amount == 0 ) if ( amount < 0 || amount == 0 )
return; // TODO: No longer signal interest in writing and disconnect. return; // TODO: No longer signal interest in writing + disconnect.
connection->outgoing_offset = (connection->outgoing_offset + amount) % connection->outgoing_size; connection->outgoing_offset = (connection->outgoing_offset + amount) %
connection->outgoing_size;
connection->outgoing_used -= amount; connection->outgoing_used -= amount;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, 2016, 2017, 2022 Jonas 'Sortie' Termansen. * Copyright (c) 2014, 2015, 2016, 2017, 2022, 2023 Jonas 'Sortie' Termansen.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -52,7 +52,7 @@ int main(int argc, char* argv[])
const char* tty = NULL; const char* tty = NULL;
int opt; int opt;
while ( (opt = getopt(argc, argv, "m:s:t")) != -1 ) while ( (opt = getopt(argc, argv, "m:s:t:")) != -1 )
{ {
switch ( opt ) switch ( opt )
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen. * Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -43,7 +43,7 @@ static int open_local_server_socket(const char* path, int flags)
{ {
size_t path_length = strlen(path); size_t path_length = strlen(path);
size_t addr_size = offsetof(struct sockaddr_un, sun_path) + path_length + 1; 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 ) if ( !sockaddr )
return -1; return -1;
sockaddr->sun_family = AF_LOCAL; sockaddr->sun_family = AF_LOCAL;
@ -93,7 +93,7 @@ void server_initialize(struct server* server, struct display* display,
err(1, "settermmode"); err(1, "settermmode");
server->pfds_count = server_pfds_count(server); server->pfds_count = server_pfds_count(server);
server->pfds = (struct pollfd*) server->pfds =
reallocarray(NULL, sizeof(struct pollfd), server->pfds_count); reallocarray(NULL, sizeof(struct pollfd), server->pfds_count);
if ( !server->pfds ) if ( !server->pfds )
err(1, "malloc"); err(1, "malloc");
@ -113,7 +113,7 @@ bool server_accept(struct server* server)
size_t new_length = server->connections_length * 2; size_t new_length = server->connections_length * 2;
if ( !new_length ) if ( !new_length )
new_length = 16; new_length = 16;
struct connection** new_connections = (struct connection**) struct connection** new_connections =
reallocarray(server->connections, new_length, reallocarray(server->connections, new_length,
sizeof(struct connection*)); sizeof(struct connection*));
if ( !new_connections ) if ( !new_connections )
@ -127,7 +127,7 @@ bool server_accept(struct server* server)
} }
size_t new_pfds_count = server_pfds_count(server) + 1; size_t new_pfds_count = server_pfds_count(server) + 1;
struct pollfd* new_pfds = (struct pollfd*) struct pollfd* new_pfds =
reallocarray(server->pfds, sizeof(struct pollfd), new_pfds_count); reallocarray(server->pfds, sizeof(struct pollfd), new_pfds_count);
if ( !new_pfds ) if ( !new_pfds )
{ {
@ -138,8 +138,7 @@ bool server_accept(struct server* server)
server->pfds = new_pfds; server->pfds = new_pfds;
server->pfds_count = new_pfds_count; server->pfds_count = new_pfds_count;
struct connection* connection = (struct connection*) struct connection* connection = malloc(sizeof(struct connection));
malloc(sizeof(struct connection));
if ( !connection ) if ( !connection )
{ {
warn("dropped connection: %s: malloc", server->server_path); warn("dropped connection: %s: malloc", server->server_path);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen. * Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, 2016, 2017 Jonas 'Sortie' Termansen. * Copyright (c) 2014, 2015, 2016, 2017, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2023 Juhani 'nortti' Krekelä. * Copyright (c) 2023 Juhani 'nortti' Krekelä.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any