Implement server_address_new()

When creating a local socket/pipe (server_start()) Neovim used vim_tempname() to
generate a unique socket path. For Windows UNIX filepaths cannot be used as
pipe names (they must start with \\.\pipe\). This commit replaces the use of
vim_tempname() for server addresses with server_address_new().

server_address_new() generates unique names for local sockets/pipes - for UNIX
it uses vim_tempname(), for Windows generates names in the form

    \\.\pipe\nvim-PID-COUNTER

where PID is the current process id, and COUNTER is a static uint32_t counter
incremented with every call. This function is now used for server_start() and
server_init() when no address is available.
This commit is contained in:
Rui Abreu Ferreira
2015-09-30 16:13:12 +01:00
parent e9de70e4ea
commit 5161f447f6
2 changed files with 24 additions and 2 deletions

View File

@@ -14572,7 +14572,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string = vim_strsave(get_tv_string(argvars)); rettv->vval.v_string = vim_strsave(get_tv_string(argvars));
} }
} else { } else {
rettv->vval.v_string = vim_tempname(); rettv->vval.v_string = (char_u *)server_address_new();
} }
int result = server_start((char *) rettv->vval.v_string); int result = server_start((char *) rettv->vval.v_string);

View File

@@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h>
#include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/server.h" #include "nvim/msgpack_rpc/server.h"
@@ -35,7 +36,7 @@ bool server_init(void)
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR); const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
if (listen_address == NULL) { if (listen_address == NULL) {
must_free = true; must_free = true;
listen_address = (char *)vim_tempname(); listen_address = server_address_new();
} }
bool ok = (server_start(listen_address) == 0); bool ok = (server_start(listen_address) == 0);
@@ -67,6 +68,27 @@ void server_teardown(void)
GA_DEEP_CLEAR(&watchers, SocketWatcher *, close_socket_watcher); GA_DEEP_CLEAR(&watchers, SocketWatcher *, close_socket_watcher);
} }
/// Generates unique address for local server.
///
/// In Windows this is a named pipe in the format
/// \\.\pipe\nvim-<PID>-<COUNTER>.
///
/// For other systems it is a path returned by vim_tempname().
///
/// This function is NOT thread safe
char *server_address_new(void)
{
#ifdef WIN32
static uint32_t count = 0;
char template[ADDRESS_MAX_SIZE];
snprintf(template, ADDRESS_MAX_SIZE,
"\\\\.\\pipe\\nvim-%" PRIu64 "-%" PRIu32, os_get_pid(), count++);
return xstrdup(template);
#else
return (char *)vim_tempname();
#endif
}
/// Starts listening for API calls on the TCP address or pipe path `endpoint`. /// Starts listening for API calls on the TCP address or pipe path `endpoint`.
/// The socket type is determined by parsing `endpoint`: If it's a valid IPv4 /// The socket type is determined by parsing `endpoint`: If it's a valid IPv4
/// address in 'ip[:port]' format, then it will be TCP socket. The port is /// address in 'ip[:port]' format, then it will be TCP socket. The port is