aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/msgpack_rpc/server.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2024-09-02 15:57:07 +0200
committerJustin M. Keyes <justinkz@gmail.com>2024-09-02 22:41:41 +0200
commit96128a5076b7e45fc01163151401a9e2acdff565 (patch)
treeb621a6b44c8f95b3db18274b4e6d0f319cdbd391 /src/nvim/msgpack_rpc/server.c
parent137f98cf6428a55b1b7687c151d8481c1deb9347 (diff)
downloadrneovim-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.c31
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