mirror of
https://github.com/neovim/neovim.git
synced 2025-09-30 15:08:35 +00:00
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
704ba4151e
, but that was basically
a workaround for the fragility of `$NVIM_LISTEN_ADDRESS`.
This commit is contained in:
@@ -93,15 +93,15 @@ void remote_ui_free_all_mem(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Wait until ui has connected on stdio channel if only_stdio
|
||||
/// is true, otherwise any channel.
|
||||
/// Wait until UI has connected.
|
||||
///
|
||||
/// @param only_stdio UI is expected to connect on stdio.
|
||||
void remote_ui_wait_for_attach(bool only_stdio)
|
||||
{
|
||||
if (only_stdio) {
|
||||
Channel *channel = find_channel(CHAN_STDIO);
|
||||
if (!channel) {
|
||||
// this function should only be called in --embed mode, stdio channel
|
||||
// can be assumed.
|
||||
// `only_stdio` implies --embed mode, thus stdio channel can be assumed.
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@@ -332,12 +332,6 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
bool use_builtin_ui = (has_term && !headless_mode && !embedded_mode && !silent_mode);
|
||||
|
||||
// don't bind the server yet, if we are using builtin ui.
|
||||
// This will be done when nvim server has been forked from the ui process
|
||||
if (!use_builtin_ui) {
|
||||
server_init(params.listen_addr);
|
||||
}
|
||||
|
||||
if (params.remote) {
|
||||
remote_request(¶ms, params.remote, params.server_addr, argc, argv,
|
||||
use_builtin_ui);
|
||||
@@ -355,11 +349,19 @@ int main(int argc, char **argv)
|
||||
ui_client_channel_id = rv;
|
||||
}
|
||||
|
||||
// NORETURN: Start builtin UI client.
|
||||
if (ui_client_channel_id) {
|
||||
time_finish();
|
||||
ui_client_run(remote_ui); // NORETURN
|
||||
}
|
||||
assert(!ui_client_channel_id && !use_builtin_ui);
|
||||
// Nvim server...
|
||||
|
||||
int listen_rv = server_init(params.listen_addr);
|
||||
if (listen_rv != 0) {
|
||||
mainerr("Failed to --listen", listen_rv < 0
|
||||
? os_strerror(listen_rv) : (listen_rv == 1 ? "empty address" : NULL));
|
||||
}
|
||||
|
||||
TIME_MSG("expanding arguments");
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user