#1065391 xtrace interactive mode stutters with multiple clients

Package:
xtrace
Source:
xtrace
Description:
trace communication between X client and server
Submitter:
Daniel Manjarres
Date:
2024-03-03 18:39:04 UTC
Severity:
normal
Tags:
#1065391#5
Date:
2024-03-03 18:34:10 UTC
From:
To:
Dear Maintainer,

The loop in main.c checks for input on multiple clients, but lines
292-305 should be outside of this loop, and only checked once per
invocation of select(). Otherwise when N clients are connected it
leads to blocking reads from stdin, typically waiting N times and then
allowing N requests through all at once.

The patch below also uses STDIN_FILENO instead of 0, for easier
readability.
--- main.c.orig 2024-03-03 09:40:41.443380046 -0800
+++ main.c      2024-03-03 10:32:13.911321696 -0800
@@ -288,21 +288,21 @@
                        }
                        continue;
                }
-               for( c = connections ; c != NULL ; c = c->next ) {
-                       if( interactive && FD_ISSET(0,&readfds) ) {
-                               char buffer[201];
-                               ssize_t isread;
-                               isread = read(0,buffer,200);
-                               if( isread == 0 )
-                                       exit(EXIT_SUCCESS);
-                               if( isread > 0 ) {
-                                       buffer[isread]='\0';
-                                       int number = atoi(buffer);
-                                       if( number <= 0 )
-                                               number = 1;
-                                       allowsent += number;
-                               }
+               if( interactive && FD_ISSET(STDIN_FILENO,&readfds) ) {
+                       char buffer[201];
+                       ssize_t isread;
+                       isread = read(STDIN_FILENO,buffer,200);
+                       if( isread == 0 )
+                               exit(EXIT_SUCCESS);
+                       if( isread > 0 ) {
+                               buffer[isread]='\0';
+                               int number = atoi(buffer);
+                               if( number <= 0 )
+                                       number = 1;
+                               allowsent += number;
                        }
+               }
+               for( c = connections ; c != NULL ; c = c->next ) {
                        if( c->client_fd != -1 ) {
                                if( FD_ISSET(c->client_fd,&exceptfds) ) {
                                        close(c->client_fd);