mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 04:21:24 +00:00
Ignore SO_RCVTIMEO errors in emacsclient
* lib-src/emacsclient.c: Include <stdckdint.h> (timeout): Now signed, and initially -1. All uses changed. (decode_options): Do not worry about ERANGE or ranges, as other code now deal with this; the old code was wrong anyway as it mixed uintmax_t with INTMAX_MAX and INTMAX_MIN. But do check for syntax errors and negative values. (set_socket_timeout): Don’t time out if the timeout is 0 or enormous. Silently ignore errors (Bug#81160). (main): Allow --timeout=0, as per documentation.
This commit is contained in:
parent
8902361cba
commit
6db4271ee8
1 changed files with 22 additions and 20 deletions
|
|
@ -74,6 +74,7 @@ char *w32_getenv (const char *);
|
|||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdckdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -146,8 +147,9 @@ static char const *socket_name;
|
|||
/* If non-NULL, the filename of the authentication file. */
|
||||
static char const *server_file;
|
||||
|
||||
/* Seconds to wait before timing out (0 means wait forever). */
|
||||
static uintmax_t timeout;
|
||||
/* Seconds to wait before timing out. Negative means no --timeout so
|
||||
use DEFAULT_TIMEOUT, 0 means wait forever. */
|
||||
static intmax_t timeout = -1;
|
||||
|
||||
/* If non-NULL, the tramp prefix emacs must use to find the files. */
|
||||
static char const *tramp_prefix;
|
||||
|
|
@ -539,10 +541,8 @@ decode_options (int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'w':
|
||||
timeout = strtoumax (optarg, &endptr, 10);
|
||||
if (timeout <= 0 ||
|
||||
((timeout == INTMAX_MAX || timeout == INTMAX_MIN)
|
||||
&& errno == ERANGE))
|
||||
timeout = strtoimax (optarg, &endptr, 10);
|
||||
if (timeout < 0 || endptr == optarg || *endptr)
|
||||
{
|
||||
fprintf (stderr, "Invalid timeout: \"%s\"\n", optarg);
|
||||
exit (EXIT_FAILURE);
|
||||
|
|
@ -1952,28 +1952,30 @@ start_daemon_and_retry_set_socket (void)
|
|||
return emacs_socket;
|
||||
}
|
||||
|
||||
/* Set SOCKET's timeout to SECONDS.
|
||||
If SECONDS is zero or out of range, do not set the timeout.
|
||||
Silently ignore errors, as POSIX says it is implementation-defined as
|
||||
to whether SO_RCVTIMEO works. Although we could fall back on
|
||||
non-blocking I/O if setsockopt fails, it's not worth the trouble. */
|
||||
static void
|
||||
set_socket_timeout (HSOCKET socket, int seconds)
|
||||
set_socket_timeout (HSOCKET socket, intmax_t seconds)
|
||||
{
|
||||
int ret;
|
||||
if (seconds <= 0)
|
||||
return;
|
||||
|
||||
#ifndef WINDOWSNT
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = seconds;
|
||||
if (ckd_add (&timeout.tv_sec, seconds, 0))
|
||||
return;
|
||||
timeout.tv_usec = 0;
|
||||
ret = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
|
||||
setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
|
||||
#else
|
||||
DWORD timeout;
|
||||
|
||||
if (seconds > INT_MAX / 1000)
|
||||
timeout = INT_MAX;
|
||||
else
|
||||
timeout = seconds * 1000;
|
||||
ret = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof timeout);
|
||||
if (ckd_mul (&timeout, seconds, 1000))
|
||||
return;
|
||||
setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof timeout);
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
sock_err_message ("setsockopt");
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2210,7 +2212,7 @@ main (int argc, char **argv)
|
|||
}
|
||||
fflush (stdout);
|
||||
|
||||
set_socket_timeout (emacs_socket, timeout > 0 ? timeout : DEFAULT_TIMEOUT);
|
||||
set_socket_timeout (emacs_socket, timeout < 0 ? DEFAULT_TIMEOUT : timeout);
|
||||
bool saw_response = false;
|
||||
ptrdiff_t nrecv = 0;
|
||||
|
||||
|
|
@ -2236,7 +2238,7 @@ main (int argc, char **argv)
|
|||
if (timeout > 0)
|
||||
{
|
||||
/* Don't retry if we were given a --timeout flag. */
|
||||
fprintf (stderr, "\nServer not responding; timed out after %ju seconds",
|
||||
fprintf (stderr, "\nServer not responding; timed out after %jd seconds",
|
||||
timeout);
|
||||
retry = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue