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;
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;
int val = 1;
channel_T *channel;
+#ifdef MSWIN
+ channel_init_winsock();
+#endif
+
channel = add_channel();
if (channel == NULL)
{
}
#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,
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;
" 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:')