diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c index d24ed83..3c94702 100644 --- a/vtest/vtest_server.c +++ b/vtest/vtest_server.c @@ -35,6 +35,7 @@ #include #include "util.h" +#include "util/u_double_list.h" #include "util/u_memory.h" #include "vtest.h" #include "vtest_protocol.h" @@ -49,6 +50,8 @@ struct vtest_client int out_fd; struct vtest_input input; + struct list_head head; + struct vtest_context *context; }; @@ -70,7 +73,7 @@ struct vtest_server int ctx_flags; - struct vtest_client client; + struct list_head active_clients; }; struct vtest_server server = { @@ -86,13 +89,6 @@ struct vtest_server server = { .loop = true, .ctx_flags = 0, - - .client = { - .in_fd = -1, - .out_fd = -1, - .input = { { -1 }, NULL }, - .context = NULL, - }, }; static void vtest_server_getenv(void); @@ -101,7 +97,7 @@ static void vtest_server_set_signal_child(void); static void vtest_server_set_signal_segv(void); static void vtest_server_open_read_file(void); static void vtest_server_open_socket(void); -static void vtest_server_run_renderer(struct vtest_client *client); +static void vtest_server_run_renderer(void); static void vtest_server_wait_for_socket_accept(void); static void vtest_server_tidy_fds(void); static void vtest_server_close_socket(void); @@ -117,6 +113,8 @@ while (__AFL_LOOP(1000)) { vtest_server_getenv(); vtest_server_parse_args(argc, argv); + list_inithead(&server.active_clients); + if (server.do_fork) { vtest_server_set_signal_child(); } else { @@ -125,14 +123,14 @@ while (__AFL_LOOP(1000)) { if (server.read_file != NULL) { vtest_server_open_read_file(); - vtest_server_run_renderer(&server.client); + vtest_server_run_renderer(); vtest_server_tidy_fds(); } else { vtest_server_open_socket(); do { vtest_server_wait_for_socket_accept(); - vtest_server_run_renderer(&server.client); + vtest_server_run_renderer(); vtest_server_tidy_fds(); } while (server.loop); @@ -277,26 +275,46 @@ static void vtest_server_set_signal_segv(void) } } +static int vtest_server_add_client(int in_fd, int out_fd) +{ + struct vtest_client *client; + + client = calloc(1, sizeof(*client)); + if (!client) + return -1; + + client->in_fd = in_fd; + client->out_fd = out_fd; + + client->input.data.fd = in_fd; + client->input.read = vtest_block_read; + + list_addtail(&client->head, &server.active_clients); + + return 0; +} + static void vtest_server_open_read_file(void) { - struct vtest_client *client = &server.client; - int ret; + int in_fd; + int out_fd; - ret = open(server.read_file, O_RDONLY); - if (ret == -1) { + in_fd = open(server.read_file, O_RDONLY); + if (in_fd == -1) { perror(NULL); exit(1); } - client->in_fd = ret; - client->input.data.fd = client->in_fd; - client->input.read = vtest_block_read; - ret = open("/dev/null", O_WRONLY); - if (ret == -1) { + out_fd = open("/dev/null", O_WRONLY); + if (out_fd == -1) { + perror(NULL); + exit(1); + } + + if (vtest_server_add_client(in_fd, out_fd)) { perror(NULL); exit(1); } - client->out_fd = ret; } static void vtest_server_open_socket(void) @@ -332,7 +350,6 @@ err: static void vtest_server_wait_for_socket_accept(void) { - struct vtest_client *client = &server.client; fd_set read_fds; int new_fd; int ret; @@ -356,10 +373,10 @@ static void vtest_server_wait_for_socket_accept(void) exit(1); } - client->in_fd = new_fd; - client->out_fd = new_fd; - client->input.data.fd = client->in_fd; - client->input.read = vtest_block_read; + if (vtest_server_add_client(new_fd, new_fd)) { + perror("Failed to add client."); + exit(1); + } } static pid_t vtest_server_fork(void) @@ -377,8 +394,10 @@ static pid_t vtest_server_fork(void) return pid; } -static void vtest_server_run_renderer(struct vtest_client *client) +static void vtest_server_run_renderer(void) { + struct vtest_client *client = + LIST_ENTRY(struct vtest_client, server.active_clients.next, head); int err, ret; if (server.do_fork) { @@ -488,7 +507,8 @@ static int vtest_client_dispatch_commands(struct vtest_client *client) static void vtest_server_tidy_fds(void) { - struct vtest_client *client = &server.client; + struct vtest_client *client = + LIST_ENTRY(struct vtest_client, server.active_clients.next, head); // out_fd will be closed by the in_fd clause if they are the same. if (client->out_fd == client->in_fd) { @@ -505,6 +525,9 @@ static void vtest_server_tidy_fds(void) close(client->out_fd); client->out_fd = -1; } + + list_del(&client->head); + free(client); } static void vtest_server_close_socket(void)