daemon: correctly handle soft accept() errors in service_loop
Since df076bdbcc ([PATCH] GIT: Listen on IPv6 as well, if available., 2005-07-23), the original error checking was included in an inner loop unchanged, where its effect was different. Instead of retrying, after a EINTR during accept() in the listening socket, it will advance to the next one and try with that instead, leaving the client waiting for another round. Make sure to retry with the same listener socket that failed originally. To avoid an unlikely busy loop, fallback to the old behaviour after a couple of attempts. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Acked-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Carlo Marcelo Arenas Belón committed
Jun 27, 2025 at 16:14 UTC
78b6601ca39015b7c6df9c5c323e9a7df74dee26
1 file changed
+10
-2
daemon.c
+10
-2
@@ -1153,11 +1153,19 @@ static int service_loop(struct socketlist *socklist)
1153
#endif
1154
} ss;
1155
socklen_t sslen = sizeof(ss);
1156
- int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
1156
+ int incoming;
1157
+ int retry = 3;
1158
+
1159
+ redo:
1160
+ incoming = accept(pfd[i].fd, &ss.sa, &sslen);
1161
if (incoming < 0) {
1162
switch (errno) {
1159
- case EAGAIN:
1163
case EINTR:
1164
+ if (--retry)
1165
+ goto redo;
1166
+
1167
+ /* fallthrough */
1168
+ case EAGAIN:
1169
case ECONNABORTED:
1170
continue;
1171
default: