diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2024-09-08 07:07:19 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-08 07:07:19 -0700 |
| commit | 08153ddd1c149c867948f4681846531d53ba7759 (patch) | |
| tree | 5bfb384613247cbffb809dfcea14cd62448d9990 /src/nvim/msgpack_rpc | |
| parent | 003b8a251dc1184e36c222f675bf79a50a40ab3a (diff) | |
| download | rneovim-08153ddd1c149c867948f4681846531d53ba7759.tar.gz rneovim-08153ddd1c149c867948f4681846531d53ba7759.tar.bz2 rneovim-08153ddd1c149c867948f4681846531d53ba7759.zip | |
fix(startup): ignore broken $XDG_RUNTIME_DIR #30285
Problem:
$XDG_RUNTIME_DIR may be broken on WSL, which prevents starting (and even
building) Nvim. #30282
Solution:
- When startup fails, mention the servername in the error message.
- If an autogenerated server address fails, log an error and continue
with an empty `v:servername`. It's only fatal if a user provides a bad
`--listen` or `$NVIM_LISTEN_ADDRESS` address.
Before:
$ nvim --headless --listen ./hello.sock
nvim: Failed to --listen: "address already in use"
$ NVIM_LISTEN_ADDRESS='./hello.sock' ./build/bin/nvim --headless
nvim: Failed to --listen: "address already in use"
After:
$ nvim --headless --listen ./hello.sock
nvim: Failed to --listen: address already in use: "./hello.sock"
$ NVIM_LISTEN_ADDRESS='./hello.sock' ./build/bin/nvim --headless
nvim: Failed $NVIM_LISTEN_ADDRESS: address already in use: "./hello.sock"
Diffstat (limited to 'src/nvim/msgpack_rpc')
| -rw-r--r-- | src/nvim/msgpack_rpc/server.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index ae34829181..9cfe46454d 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -11,12 +11,14 @@ #include "nvim/event/socket.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" +#include "nvim/globals.h" #include "nvim/log.h" #include "nvim/main.h" #include "nvim/memory.h" #include "nvim/msgpack_rpc/server.h" #include "nvim/os/os.h" #include "nvim/os/stdpaths_defs.h" +#include "nvim/types_defs.h" #define MAX_CONNECTIONS 32 #define ENV_LISTEN "NVIM_LISTEN_ADDRESS" // deprecated @@ -27,20 +29,24 @@ static garray_T watchers = GA_EMPTY_INIT_VALUE; # include "msgpack_rpc/server.c.generated.h" #endif -/// Initializes the module +/// Initializes resources, handles `--listen`, starts the primary server at v:servername. /// -/// @returns 0: success, 1: validation error, 2: already listening, -errno: failed to bind/listen. -int server_init(const char *listen_addr) +/// @returns true on success, false on fatal error (message stored in IObuff) +bool server_init(const char *listen_addr) { + bool ok = true; bool must_free = false; + TriState user_arg = kTrue; // User-provided --listen arg. ga_init(&watchers, sizeof(SocketWatcher *), 1); // $NVIM_LISTEN_ADDRESS (deprecated) if ((!listen_addr || listen_addr[0] == '\0') && os_env_exists(ENV_LISTEN)) { + user_arg = kFalse; // User-provided env var. listen_addr = os_getenv(ENV_LISTEN); } if (!listen_addr || listen_addr[0] == '\0') { + user_arg = kNone; // Autogenerated server address. listen_addr = server_address_new(NULL); must_free = true; } @@ -51,12 +57,6 @@ int server_init(const char *listen_addr) int rv = server_start(listen_addr); - if (os_env_exists(ENV_LISTEN)) { - // 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); - } - // TODO(justinmk): this is for logging_spec. Can remove this after nvim_log #7062 is merged. if (os_env_exists("__NVIM_TEST_LOG")) { ELOG("test log message"); @@ -66,7 +66,28 @@ int server_init(const char *listen_addr) xfree((char *)listen_addr); } - return rv; + if (rv == 0 || user_arg == kNone) { + // The autogenerated servername can fail if the user has a broken $XDG_RUNTIME_DIR. #30282 + // But that is not fatal (startup will continue, logged in $NVIM_LOGFILE, empty v:servername). + goto end; + } + + (void)snprintf(IObuff, IOSIZE, + user_arg == + kTrue ? "Failed to --listen: %s: \"%s\"" + : "Failed $NVIM_LISTEN_ADDRESS: %s: \"%s\"", + rv < 0 ? os_strerror(rv) : (rv == 1 ? "empty address" : "?"), + listen_addr ? listen_addr : "(empty)"); + ok = false; + +end: + if (os_env_exists(ENV_LISTEN)) { + // 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); + } + + return ok; } /// Teardown a single server |