diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2014-10-17 14:03:58 -0400 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2014-10-17 14:03:58 -0400 |
commit | 56ef9e86688e79dc6a6bffe73c505eaaddf3be2d (patch) | |
tree | e51b992da450422eae6d25917dd8de55b726fa38 | |
parent | 587101a3746fac401c3fdace35d09cbcb8d38571 (diff) | |
parent | 792882e9e415e7dfb26e0778d760003a7d4747e1 (diff) | |
download | rneovim-56ef9e86688e79dc6a6bffe73c505eaaddf3be2d.tar.gz rneovim-56ef9e86688e79dc6a6bffe73c505eaaddf3be2d.tar.bz2 rneovim-56ef9e86688e79dc6a6bffe73c505eaaddf3be2d.zip |
Merge pull request #1297 from splinterofchaos/server-errors
server: Improve error reporting.
-rw-r--r-- | src/nvim/os/server.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/src/nvim/os/server.c b/src/nvim/os/server.c index 66dd0ecd88..9f7f5b34da 100644 --- a/src/nvim/os/server.c +++ b/src/nvim/os/server.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <stdlib.h> #include <string.h> #include <stdint.h> @@ -13,6 +14,7 @@ #include "nvim/message.h" #include "nvim/tempfile.h" #include "nvim/map.h" +#include "nvim/path.h" #define MAX_CONNECTIONS 32 #define ADDRESS_MAX_SIZE 256 @@ -48,7 +50,7 @@ static PMap(cstr_t) *servers = NULL; #endif /// Initializes the module -void server_init(void) +bool server_init(void) { servers = pmap_new(cstr_t)(); @@ -58,7 +60,7 @@ void server_init(void) free(listen_address); } - server_start((char *)os_getenv(LISTEN_ADDRESS_ENV_VAR)); + return server_start((char *)os_getenv(LISTEN_ADDRESS_ENV_VAR)) == 0; } /// Teardown the server module @@ -89,7 +91,10 @@ void server_teardown(void) /// @param endpoint Address of the server. Either a 'ip[:port]' string or an /// arbitrary identifier(trimmed to 256 bytes) for the unix socket or /// named pipe. -void server_start(char *endpoint) +/// @returns zero if successful, one on a regular error, and negative errno +/// on failure to bind or connect. +int server_start(const char *endpoint) + FUNC_ATTR_NONNULL_ALL { char addr[ADDRESS_MAX_SIZE]; @@ -103,7 +108,7 @@ void server_start(char *endpoint) // Check if the server already exists if (pmap_has(cstr_t)(servers, addr)) { EMSG2("Already listening on %s", addr); - return; + return 1; } ServerType server_type = kServerTypeTcp; @@ -151,40 +156,56 @@ void server_start(char *endpoint) // Listen on tcp address/port uv_tcp_init(uv_default_loop(), &server->socket.tcp.handle); server->socket.tcp.handle.data = server; - uv_tcp_bind(&server->socket.tcp.handle, + result = uv_tcp_bind(&server->socket.tcp.handle, (const struct sockaddr *)&server->socket.tcp.addr, 0); - result = uv_listen((uv_stream_t *)&server->socket.tcp.handle, - MAX_CONNECTIONS, - connection_cb); - if (result) { - uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server); + if (result == 0) { + result = uv_listen((uv_stream_t *)&server->socket.tcp.handle, + MAX_CONNECTIONS, + connection_cb); + if (result) { + uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server); + } } } else { // Listen on named pipe or unix socket xstrlcpy(server->socket.pipe.addr, addr, sizeof(server->socket.pipe.addr)); uv_pipe_init(uv_default_loop(), &server->socket.pipe.handle, 0); server->socket.pipe.handle.data = server; - uv_pipe_bind(&server->socket.pipe.handle, server->socket.pipe.addr); - result = uv_listen((uv_stream_t *)&server->socket.pipe.handle, - MAX_CONNECTIONS, - connection_cb); - - if (result) { - uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server); + result = uv_pipe_bind(&server->socket.pipe.handle, + server->socket.pipe.addr); + if (result == 0) { + result = uv_listen((uv_stream_t *)&server->socket.pipe.handle, + MAX_CONNECTIONS, + connection_cb); + + if (result) { + uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server); + } } } - if (result) { + assert(result <= 0); // libuv should have returned -errno or zero. + if (result < 0) { + if (result == -EACCES) { + // Libuv converts ENOENT to EACCES for Windows compatibility, but if + // the parent directory does not exist, ENOENT would be more accurate. + *path_tail((char_u *) addr) = NUL; + if (!os_file_exists((char_u *) addr)) { + result = -ENOENT; + } + } EMSG2("Failed to start server: %s", uv_strerror(result)); - return; + free(server); + return result; } - server->type = server_type; // Add the server to the hash table pmap_put(cstr_t)(servers, addr, server); + + return 0; } /// Stops listening on the address specified by `endpoint`. |