Repository navigation
fix(ports): scope the TCP scan timeout to the scanning socket - #3701
Merged
nicolargo merged 1 commit intoAug 29, 2026
Merged
Conversation
socket.setdefaulttimeout() is process-wide and was never restored, so once a port had been scanned every socket created afterwards anywhere in Glances that does not set its own timeout inherited the last scanned port's timeout -- the hddtemp grabber among them. _socket.settimeout() sets the same value on the socket the scan actually uses and leaves the rest of the process alone. Scan results are unchanged. Also return when the socket cannot be created: the code fell through with _socket unbound, so connect_ex raised UnboundLocalError into the 'Error while scanning port' handler and the finally clause raised it again with nothing left to catch it.
Owner
|
Thanks (again) @ntdatt812 Just merged into develop. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_port_scan_tcpconfigures its socket withsocket.setdefaulttimeout(), which is process-wide, not per-socket — and nothing restores it. After the first port is scanned, every socket created afterwards anywhere in Glances that does not set its own timeout silently inherits the last scanned port'stimeout.Measured on
develop, one scan of a closed port withtimeout = 3:Line 3 is the point:
GlancesGrabHDDTemp.fetch()builds its socket with no timeout of its own, so what it gets now depends on whether the ports plugin happened to run first and on which port it scanned last. Nothing in the tree readssocket.getdefaulttimeout(), so this is not load-bearing anywhere — it is only reach._socket.settimeout()sets the same value on the socket the scan actually uses, and leaves the rest of the process alone. Scan results are unchanged:connect_exbehaves the same whether the timeout arrived from the global default or from the socket.A second defect in the same function
If the socket cannot be created the function keeps going with
_socketunbound. Theconnect_exfailure is swallowed by the "Error while scanning port" handler, which names the wrong thing, and then thefinallyraises the same error with no handler left:Returning early in the
exceptfixes both.Tests
tests/test_plugin_ports.pygrows aTestTcpScanSocketclass: 13 → 17.Reverting only
glances/plugins/ports/__init__.pyand keeping the tests:With the fix: 17 passed.
ruff checkandruff format --checkclean on both files.One note on the first of those two, because it nearly went in useless: it originally read the default timeout at the top and asserted the scan did not change it. That passes on
develop— an earlier test in the same session has already set the global to 3, so "unchanged" is trivially true against exactly the state the test exists to forbid. It now pins the default toNonefirst and restores it afterwards, which is what makes it fail without the fix.The other two cases in the class pin behaviour rather than catching the regression: the scanning socket carries the timeout, and a closed port is still reported offline. Both pass either way, and they are there so a future rewrite cannot quietly drop the timeout or change the result.
The full suite was run on
developand on this branch with the same invocation(
pytest tests/ -q -p no:randomly), and the failure names diffed in both directions:developThe two failure sets are identical —
commreturns nothing in either direction — and the+4 is exactly the four tests added here. Those 67 pre-existing failures are all in
test_restful.py,test_xmlrpc.py,test_mcp.py,test_browser_restful.py,test_webui.pyandtest_perf.py, i.e. the integration tests that need a running serveror node on this (Windows) machine. None are in
test_plugin_*.