diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2024-09-02 15:57:07 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2024-09-02 22:41:41 +0200 |
commit | 96128a5076b7e45fc01163151401a9e2acdff565 (patch) | |
tree | b621a6b44c8f95b3db18274b4e6d0f319cdbd391 /src/nvim/msgpack_rpc/server.c | |
parent | 137f98cf6428a55b1b7687c151d8481c1deb9347 (diff) | |
download | rneovim-96128a5076b7e45fc01163151401a9e2acdff565.tar.gz rneovim-96128a5076b7e45fc01163151401a9e2acdff565.tar.bz2 rneovim-96128a5076b7e45fc01163151401a9e2acdff565.zip |
feat(startup): validate --listen address
Problem:
`nvim --listen` does not error on EADDRINUSE. #30123
Solution:
Now that `$NVIM_LISTEN_ADDRESS` is deprecated and input *only* (instead
of the old, ambiguous situation where it was both an input *and* an
output), we can be fail fast instead of trying to "recover". This
reverts the "recovery" behavior of
704ba4151e7f67999510ee0ac19fdabb595d530c, but that was basically
a workaround for the fragility of `$NVIM_LISTEN_ADDRESS`.
Diffstat (limited to 'src/nvim/msgpack_rpc/server.c')
-rw-r--r-- | src/nvim/msgpack_rpc/server.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index 24bd343a34..ae34829181 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -28,27 +28,32 @@ static garray_T watchers = GA_EMPTY_INIT_VALUE; #endif /// Initializes the module -bool server_init(const char *listen_addr) +/// +/// @returns 0: success, 1: validation error, 2: already listening, -errno: failed to bind/listen. +int server_init(const char *listen_addr) { + bool must_free = false; ga_init(&watchers, sizeof(SocketWatcher *), 1); // $NVIM_LISTEN_ADDRESS (deprecated) - if (!listen_addr && os_env_exists(ENV_LISTEN)) { + if ((!listen_addr || listen_addr[0] == '\0') && os_env_exists(ENV_LISTEN)) { listen_addr = os_getenv(ENV_LISTEN); } - int rv = listen_addr ? server_start(listen_addr) : 1; - if (0 != rv) { + if (!listen_addr || listen_addr[0] == '\0') { listen_addr = server_address_new(NULL); - if (!listen_addr) { - return false; - } - rv = server_start(listen_addr); - xfree((char *)listen_addr); + must_free = true; + } + + if (!listen_addr) { + abort(); // Cannot happen. } + int rv = server_start(listen_addr); + if (os_env_exists(ENV_LISTEN)) { - // Unset $NVIM_LISTEN_ADDRESS, it's a liability hereafter. + // Unset $NVIM_LISTEN_ADDRESS, it's a liability hereafter. It is "input only", it must not be + // leaked to child jobs or :terminal. os_unsetenv(ENV_LISTEN); } @@ -57,7 +62,11 @@ bool server_init(const char *listen_addr) ELOG("test log message"); } - return rv == 0; + if (must_free) { + xfree((char *)listen_addr); + } + + return rv; } /// Teardown a single server |