Skip to content

fix(net): use fd+1 instead of FD_SETSIZE in select() calls#532

Open
somethingwithproof wants to merge 1 commit intoCacti:developfrom
somethingwithproof:fix/select-fd-setsize
Open

fix(net): use fd+1 instead of FD_SETSIZE in select() calls#532
somethingwithproof wants to merge 1 commit intoCacti:developfrom
somethingwithproof:fix/select-fd-setsize

Conversation

@somethingwithproof
Copy link
Copy Markdown
Contributor

select() first argument should be the highest fd + 1, not FD_SETSIZE. Passing FD_SETSIZE scans up to 1024 fds unnecessarily. The ICMP ping path already used icmp_socket+1 correctly; this fixes the UDP ping and poller script pipe paths to match.

select() first argument should be the highest fd + 1, not FD_SETSIZE.
Passing FD_SETSIZE is wasteful (scans up to 1024 fds) and technically
incorrect per POSIX. The ICMP ping path already used icmp_socket+1
correctly; fix the UDP ping and poller script pipe paths to match.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Copilot AI review requested due to automatic review settings April 8, 2026 19:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates select() usage to pass the highest monitored file descriptor + 1 (instead of FD_SETSIZE) to avoid unnecessary scanning and align behavior across ping/script paths.

Changes:

  • Update poller.c script pipe select() call to use cmd_fd + 1.
  • Update ping.c UDP ping select() call to use udp_socket + 1.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
poller.c Uses cmd_fd + 1 for select() when waiting for script pipe output.
ping.c Uses udp_socket + 1 for select() when waiting for UDP ping responses.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 651 to 654
/* wait for a response on the socket */
wait_more:
return_code = select(FD_SETSIZE, &socket_fds, NULL, NULL, &timeout);
return_code = select(udp_socket + 1, &socket_fds, NULL, NULL, &timeout);

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

select() modifies both the fd_set and the timeout structure in-place, and POSIX leaves their contents unspecified on error (including EINTR). In this loop, socket_fds is only initialized once before while (1), then reused across retries and the goto wait_more path, which can leave the set empty after the first timeout/error and prevent subsequent retries from ever observing udp_socket readability. Re-initialize socket_fds (and ensure timeout is in the intended state) immediately before each select() call, including when retrying after EINTR.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct that select() modifies the fd_set and timeout. Both are reinitialized before each select call in the existing code (FD_ZERO+FD_SET before each call). The timeout struct is also re-set. No regression.

@somethingwithproof
Copy link
Copy Markdown
Contributor Author

Review note: this PR appears obsolete. On develop, ping.c:649 already calls spine_socket_wait_readable(icmp_socket, &timeout) (added via #524's platform shims), and platform_fd_posix.c:28 already uses select(fd + 1, ...) internally. The raw select(FD_SETSIZE, ...) calls this PR targets are no longer present on develop. Suggest closing if the wrapper coverage is confirmed complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants