<div dir="ltr"><div>Thanks for the insight.</div><div><br></div><div>I can't quickly make a value judgement on the choice of non-blocking mode - existing NUT codebase uses both O_NDELAY (seemingly in code dealing with Unix or TCP sockets, including the case here with upssched daemon/CLI interactions) and O_NONBLOCK (seemingly for serial-port connections, and for TCP sockets in nutclient.cpp `Socket::connect()` and upsclient.c `upscli_tryconnect()`).</div><div><br></div><div>Otherwise, what you describe as poll() returning no error and read() returning a 0 - that does match the situation I see.</div><div><br></div><div>My memory is vague on what @dtsecon tried to achieve in PR 1274 by adding this line to `if (ret==0) continue` (possibly worked around some delays? are those possible after the select() says the FD is ready?) - and so if that use-case gets broken again by bailing out quickly here. I guess my proposal in <a href="https://github.com/networkupstools/nut/pull/1965">https://github.com/networkupstools/nut/pull/1965</a> - which is to only immediately abort if explicit errors are seen, and abort after trying to read() hard enough - is sort of best of two worlds, or least-worst :) WDYT?<br></div><div><br></div><div>Jim<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 14, 2023 at 3:15 PM Sam Varshavchik <<a href="mailto:mrsam@courier-mta.com">mrsam@courier-mta.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Jim Klimov via Nut-upsuser writes:<br>
<br>
> So... determining that FD is to be reaped proved hard. Internet lore suggests  <br>
> fcntl() and poll() on the FD, but it just seems valid to them. The errno is  <br>
> also usually not raised (once I saw a "111: Connection refused" though).<br>
> So the best dumb idea so far is to bail out if we spent the whole loop (128  <br>
> attempts) and only got zero-sized read replies and no errors.<br>
<br>
It's been my experience, that the path of least resistance is:<br>
<br>
1) The sockets are sets to be non-blocking<br>
2) poll()<br>
3) If poll() says the socket is readable, and read() returns <= 0, then the  <br>
socket is dead. You get no error, and read() returns 0, if the socket had an  <br>
orderly shutdown.<br>
<br>
_______________________________________________<br>
Nut-upsdev mailing list<br>
<a href="mailto:Nut-upsdev@alioth-lists.debian.net" target="_blank">Nut-upsdev@alioth-lists.debian.net</a><br>
<a href="https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsdev" rel="noreferrer" target="_blank">https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsdev</a><br>
</blockquote></div>