From 5161f447f6dfb13082c6cdebb1b5806e0e3d6a16 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Wed, 30 Sep 2015 16:13:12 +0100 Subject: 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. --- src/nvim/eval.c | 2 +- src/nvim/msgpack_rpc/server.c | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d02348028a..a1ac713a75 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14572,7 +14572,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv) rettv->vval.v_string = vim_strsave(get_tv_string(argvars)); } } 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); diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index 8dffea35ca..61b8206eb6 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "nvim/msgpack_rpc/channel.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); if (listen_address == NULL) { must_free = true; - listen_address = (char *)vim_tempname(); + listen_address = server_address_new(); } bool ok = (server_start(listen_address) == 0); @@ -67,6 +68,27 @@ void server_teardown(void) 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--. +/// +/// 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`. /// 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 -- cgit From 3e84a91ac1adf120f75f8382e8c71601d3655059 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Fri, 2 Oct 2015 00:24:20 +0100 Subject: Allow server_start to accept a NULL argument Return 1 if the endpoint argument is NULL, server_start() can get a NULL value when using server_address_new() or vim_tempname(). Removed the function attribute. --- src/nvim/msgpack_rpc/server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index 61b8206eb6..474e25ffeb 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -101,8 +101,12 @@ char *server_address_new(void) /// @returns 0 on success, 1 on a regular error, and negative errno /// on failure to bind or connect. int server_start(const char *endpoint) - FUNC_ATTR_NONNULL_ALL { + if (endpoint == NULL) { + ELOG("Attempting to start server on NULL endpoint"); + return 1; + } + SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher)); socket_watcher_init(&loop, watcher, endpoint, NULL); -- cgit