(tcp_listen, posix_setsockopt) [_WIN32]: Move the special
SO_REUSEADDR code for _WIN32 from tcp_listen() to posix_setsockopt(). [_WIN32] (posix_open): Switch to _sopen() for _sopen_s() as MinGW does not support _sopen_s() yet. [_WIN32] (posix_fd2socket): Fix typo.
This commit is contained in:
parent
b892774785
commit
01625ead8c
2 changed files with 18 additions and 18 deletions
|
@ -77,19 +77,8 @@ tcp_listen(char *host, char *serv, size_t *addrlenp)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
continue; /* error, try next one */
|
continue; /* error, try next one */
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/*
|
|
||||||
* SO_REUSEADDR requests to permit another bind even when the
|
|
||||||
* port is still in state TIME_WAIT. Windows' SO_REUSEADDR is
|
|
||||||
* broken: it makes bind() succeed no matter what, even if
|
|
||||||
* there's another server running on the same port. Luckily,
|
|
||||||
* bind() seems to be broken as well: it seems to succeed while
|
|
||||||
* the port is in state TIME_WAIT by default; thus we get the
|
|
||||||
* behavior we want by not setting SO_REUSEADDR.
|
|
||||||
*/
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||||
cant_listen(host, serv, strerror(errno));
|
cant_listen(host, serv, strerror(errno));
|
||||||
#endif
|
|
||||||
if (bind(fd, res->ai_addr, res->ai_addrlen) == 0)
|
if (bind(fd, res->ai_addr, res->ai_addrlen) == 0)
|
||||||
break; /* success */
|
break; /* success */
|
||||||
|
|
||||||
|
@ -134,11 +123,8 @@ tcp_listen(char *host, char *serv, size_t *addrlenp)
|
||||||
}
|
}
|
||||||
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
cant_listen(host, serv, strerror(errno));
|
cant_listen(host, serv, strerror(errno));
|
||||||
#ifndef _WIN32
|
|
||||||
/* see comment on setsockopt() above */
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||||
cant_listen(host, serv, strerror(errno));
|
cant_listen(host, serv, strerror(errno));
|
||||||
#endif
|
|
||||||
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||||
cant_listen(host, serv, strerror(errno));
|
cant_listen(host, serv, strerror(errno));
|
||||||
if (listen(fd, SOMAXCONN) < 0)
|
if (listen(fd, SOMAXCONN) < 0)
|
||||||
|
|
|
@ -193,7 +193,7 @@ int
|
||||||
posix_fd2socket(int fd)
|
posix_fd2socket(int fd)
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
enum dmap_io_type type;
|
enum fdmap_io_type type;
|
||||||
|
|
||||||
if (!lookup_handle(fd, FDMAP_IO_SOCKET, WSAENOTSOCK,
|
if (!lookup_handle(fd, FDMAP_IO_SOCKET, WSAENOTSOCK,
|
||||||
&type, &handle))
|
&type, &handle))
|
||||||
|
@ -271,8 +271,22 @@ int
|
||||||
posix_setsockopt(int fd, int level, int optname,
|
posix_setsockopt(int fd, int level, int optname,
|
||||||
const char *optval, int optlen)
|
const char *optval, int optlen)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* SO_REUSEADDR requests from tcp_listen.c
|
||||||
|
* to permit another bind even when the
|
||||||
|
* port is still in state TIME_WAIT. Windows' SO_REUSEADDR is
|
||||||
|
* broken: it makes bind() succeed no matter what, even if
|
||||||
|
* there's another server running on the same port. Luckily,
|
||||||
|
* bind() seems to be broken as well: it seems to succeed while
|
||||||
|
* the port is in state TIME_WAIT by default; thus we get the
|
||||||
|
* behavior we want by not setting SO_REUSEADDR.
|
||||||
|
*/
|
||||||
|
if (level == SOL_SOCKET && optname == SO_REUSEADDR)
|
||||||
|
return 0;
|
||||||
|
{
|
||||||
SOCKET_FUNCTION(setsockopt(handle, level, optname,
|
SOCKET_FUNCTION(setsockopt(handle, level, optname,
|
||||||
optval, optlen))
|
optval, optlen))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -404,7 +418,7 @@ posix_open(const char *fname, int oflag, ...)
|
||||||
* We don't implement fcntl() for F_SETLK. Instead, we lock *all*
|
* We don't implement fcntl() for F_SETLK. Instead, we lock *all*
|
||||||
* files we open. Not ideal, but it works for Empire.
|
* files we open. Not ideal, but it works for Empire.
|
||||||
*/
|
*/
|
||||||
_sopen_s(&handle, fname, oflag,
|
handle = _sopen(fname, oflag,
|
||||||
oflag & O_RDONLY ? SH_DENYNO : SH_DENYWR, pmode);
|
oflag & O_RDONLY ? SH_DENYNO : SH_DENYWR, pmode);
|
||||||
if (handle == -1) {
|
if (handle == -1) {
|
||||||
free_fd(new_fd);
|
free_fd(new_fd);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue