• Robert Sprowson's avatar
    Fix to SO_SNDTIMEO and SO_RCVTIMEO options being ignored · 2f20b5d4
    Robert Sprowson authored
    The TCPIPLibs library docs remind us that a socket can be modified via setsockopt() to have a non-default timeout for receive (SO_RCVTIMEO) and send (SO_SNDTIMEO) operations, however neither of these options were honoured if set. Instead, a default timeout of ~60s was given.
    This is because although the Internet module stores and propagates (via sbwait()) the timeouts correctly, the underlying tsleep() function is non compliant: it makes no distinction between returning due to a timeout and returning due to being awoken by an event. See
      https://www.freebsd.org/cgi/man.cgi?query=tsleep&sektion=9&manpath=FreeBSD+4.4-RELEASE
    
    for details.
    
    lib/unixenv.c: differentiate between timing out and being awoken, and return EWOULDBLOCK for timeouts.
    
    Aside: select() worked because when tsleep() returned with 0 for a timeout this caused a retry attempt, and the retry loop happens to include its own timer compare, causing select() to return. Now that tsleep() returns EWOULDBLOCK in a timeout situation no retry occurs and the function returns directly.
    
    Tested with a deliberately timing out receive operation, see TCPIPLibs/test/timeo.c
    Tested on RISC OS and FreeBSD 11.1-RELEASE-p4 with both an unset timeout (~60s) and 10s timeout, both behave identically in terms of return value and setting errno appropriately.
    
    Version 5.65. Tagged as 'Internet-5_65'
    2f20b5d4
unixenv 17 KB