I noticed that if gmniserve ever has to realloc the fds array because it had over 1024 simultaneous clients, then all the pollfd pointers saved in client structs become invalid.
Additionally, if two clients (1 and 2) are being served simultaneously and then client 1 disconnects first, then client 2's pollfd is shifted earlier in the array, but its pollfd pointer is not updated.
The first issue can be solved by keeping track of array indices instead of pointers. To solve the second issue, upon client disconnection you could loop through all subsequent clients and adjust their pollfd index.
Hm, a more robust solution would probably be to store the index in the client and set the fd to -1 in the pollfd to indicate that it's available.
Yes, I think that should work. You could also go further and keep a parallel array containing a linked list of free pollfd indices. When a client exits, just update its index in the free list with the previous head, and when you accept a new client, check if there are any free pollfds before reallocating the array. I'm not sure if the extra complexity is worth it over just scanning the array for a free index, though.