mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0170: channel: some issues in ch_listen()
Problem: channel: some issues in ch_listen()
(char101, after v9.2.0153)
Solution: On MS-Windows, initialize using channel_init_winsock() and use
SO_EXCLUSIVEADDRUSE instead of SO_REUSEADDR, allow to use port
0 to have the OS assign a port (Yasuhiro Matsumoto).
related: #19231
closes: #19690
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
751b59e539
commit
e05d897258
+17
-3
@@ -1440,7 +1440,7 @@ channel_listen_func(typval_T *argvars)
|
||||
return NULL;
|
||||
}
|
||||
port = strtol((char *)(p + 1), &rest, 10);
|
||||
if (port <= 0 || port >= 65536 || *rest != NUL)
|
||||
if (port < 0 || port >= 65536 || *rest != NUL)
|
||||
{
|
||||
semsg(_(e_invalid_argument_str), address);
|
||||
return NULL;
|
||||
@@ -1459,7 +1459,7 @@ channel_listen_func(typval_T *argvars)
|
||||
return NULL;
|
||||
}
|
||||
port = strtol((char *)(p + 1), &rest, 10);
|
||||
if (port <= 0 || port >= 65536 || *rest != NUL)
|
||||
if (port < 0 || port >= 65536 || *rest != NUL)
|
||||
{
|
||||
semsg(_(e_invalid_argument_str), address);
|
||||
return NULL;
|
||||
@@ -1511,6 +1511,10 @@ channel_listen(
|
||||
int val = 1;
|
||||
channel_T *channel;
|
||||
|
||||
#ifdef MSWIN
|
||||
channel_init_winsock();
|
||||
#endif
|
||||
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
{
|
||||
@@ -1555,7 +1559,7 @@ channel_listen(
|
||||
}
|
||||
|
||||
#ifdef MSWIN
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
||||
(const char *)&val, sizeof(val)) < 0)
|
||||
#else
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
|
||||
@@ -1591,6 +1595,16 @@ channel_listen(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// When port 0 was specified, retrieve the actual port assigned by the OS.
|
||||
if (port_in == 0)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
|
||||
if (getsockname(sd, (struct sockaddr *)&addr, &addr_len) == 0)
|
||||
port_in = ntohs(addr.sin_port);
|
||||
}
|
||||
|
||||
channel->ch_listen = TRUE;
|
||||
channel->CH_SOCK_FD = (sock_T)sd;
|
||||
channel->ch_nb_close_cb = nb_close_cb;
|
||||
|
||||
@@ -2798,8 +2798,11 @@ func Test_listen_invalid_address()
|
||||
" port number too large
|
||||
call assert_fails("call ch_listen('localhost:99999')", 'E475:')
|
||||
|
||||
" port number zero
|
||||
call assert_fails("call ch_listen('localhost:0')", 'E475:')
|
||||
" port number zero should let the OS assign an available port
|
||||
let ch = ch_listen('localhost:0')
|
||||
call assert_equal('open', ch_status(ch))
|
||||
call assert_notequal(0, ch_info(ch).port)
|
||||
call ch_close(ch)
|
||||
|
||||
" port number negative
|
||||
call assert_fails("call ch_listen('localhost:-1')", 'E475:')
|
||||
|
||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
170,
|
||||
/**/
|
||||
169,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user