Improve windows support
This commit is contained in:
@@ -3156,6 +3156,42 @@ bool socket_died(Socket *sock)
|
|||||||
|
|
||||||
// TODO: when is the pending_connect data freed?
|
// TODO: when is the pending_connect data freed?
|
||||||
|
|
||||||
|
static bool connect_pending(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return WSAGetLastError() == WSAEWOULDBLOCK;
|
||||||
|
#else
|
||||||
|
return errno == EINPROGRESS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
connect_failed_because_or_peer_2(int err)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return err == WSAECONNREFUSED
|
||||||
|
|| err == WSAETIMEDOUT
|
||||||
|
|| err == WSAENETUNREACH
|
||||||
|
|| err == WSAEHOSTUNREACH;
|
||||||
|
#else
|
||||||
|
return errno == ECONNREFUSED
|
||||||
|
|| errno == ETIMEDOUT
|
||||||
|
|| errno == ENETUNREACH
|
||||||
|
|| errno == EHOSTUNREACH;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
connect_failed_because_or_peer(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
#else
|
||||||
|
int err = errno;
|
||||||
|
#endif
|
||||||
|
return connect_failed_because_or_peer_2(err);
|
||||||
|
}
|
||||||
|
|
||||||
// Processes the socket until it's either ready, died, or would block
|
// Processes the socket until it's either ready, died, or would block
|
||||||
void socket_update(Socket *sock)
|
void socket_update(Socket *sock)
|
||||||
{
|
{
|
||||||
@@ -3263,8 +3299,8 @@ void socket_update(Socket *sock)
|
|||||||
again = true;
|
again = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0 && errno == EINPROGRESS) { // TODO: I'm pretty sure all the error numbers need to be changed for windows
|
if (connect_pending()) { // TODO: I'm pretty sure all the error numbers need to be changed for windows
|
||||||
// Connection pending
|
// Connection pending
|
||||||
sock->raw = raw;
|
sock->raw = raw;
|
||||||
sock->state = SOCKET_STATE_CONNECTING;
|
sock->state = SOCKET_STATE_CONNECTING;
|
||||||
@@ -3275,7 +3311,7 @@ void socket_update(Socket *sock)
|
|||||||
// Connect failed
|
// Connect failed
|
||||||
|
|
||||||
// If remote peer not working, try next address
|
// If remote peer not working, try next address
|
||||||
if (errno == ECONNREFUSED || errno == ETIMEDOUT || errno == ENETUNREACH || errno == EHOSTUNREACH) {
|
if (connect_failed_because_or_peer()) {
|
||||||
sock->state = SOCKET_STATE_PENDING;
|
sock->state = SOCKET_STATE_PENDING;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
again = true;
|
again = true;
|
||||||
@@ -3298,7 +3334,7 @@ void socket_update(Socket *sock)
|
|||||||
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
|
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
|
||||||
|
|
||||||
// If remote peer not working, try next address
|
// If remote peer not working, try next address
|
||||||
if (err == ECONNREFUSED || err == ETIMEDOUT || err == ENETUNREACH || err == EHOSTUNREACH) {
|
if (connect_failed_because_or_peer_2(err)) {
|
||||||
sock->state = SOCKET_STATE_PENDING;
|
sock->state = SOCKET_STATE_PENDING;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
again = true;
|
again = true;
|
||||||
@@ -3488,6 +3524,25 @@ void socket_update(Socket *sock)
|
|||||||
} while (again);
|
} while (again);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool would_block(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
return err == WSAEWOULDBLOCK;
|
||||||
|
#else
|
||||||
|
return errno == EAGAIN || errno == EWOULDBLOCK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool interrupted(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return errno == EINTR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int socket_read(Socket *sock, char *dst, int max)
|
int socket_read(Socket *sock, char *dst, int max)
|
||||||
{
|
{
|
||||||
// If not ESTABLISHED, set state to DIED and return
|
// If not ESTABLISHED, set state to DIED and return
|
||||||
@@ -3504,11 +3559,11 @@ int socket_read(Socket *sock, char *dst, int max)
|
|||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
} else {
|
} else {
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (would_block()) {
|
||||||
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
||||||
sock->events = POLLIN;
|
sock->events = POLLIN;
|
||||||
} else {
|
} else {
|
||||||
if (errno != EINTR) {
|
if (!interrupted()) {
|
||||||
sock->state = SOCKET_STATE_DIED;
|
sock->state = SOCKET_STATE_DIED;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
}
|
}
|
||||||
@@ -3556,11 +3611,11 @@ int socket_write(Socket *sock, char *src, int len)
|
|||||||
if (!socket_secure(sock)) {
|
if (!socket_secure(sock)) {
|
||||||
int ret = send(sock->raw, src, len, 0);
|
int ret = send(sock->raw, src, len, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (would_block()) {
|
||||||
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
||||||
sock->events = POLLOUT;
|
sock->events = POLLOUT;
|
||||||
} else {
|
} else {
|
||||||
if (errno != EINTR) {
|
if (!interrupted()) {
|
||||||
sock->state = SOCKET_STATE_DIED;
|
sock->state = SOCKET_STATE_DIED;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-8
@@ -260,6 +260,42 @@ bool socket_died(Socket *sock)
|
|||||||
|
|
||||||
// TODO: when is the pending_connect data freed?
|
// TODO: when is the pending_connect data freed?
|
||||||
|
|
||||||
|
static bool connect_pending(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return WSAGetLastError() == WSAEWOULDBLOCK;
|
||||||
|
#else
|
||||||
|
return errno == EINPROGRESS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
connect_failed_because_or_peer_2(int err)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return err == WSAECONNREFUSED
|
||||||
|
|| err == WSAETIMEDOUT
|
||||||
|
|| err == WSAENETUNREACH
|
||||||
|
|| err == WSAEHOSTUNREACH;
|
||||||
|
#else
|
||||||
|
return errno == ECONNREFUSED
|
||||||
|
|| errno == ETIMEDOUT
|
||||||
|
|| errno == ENETUNREACH
|
||||||
|
|| errno == EHOSTUNREACH;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
connect_failed_because_or_peer(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
#else
|
||||||
|
int err = errno;
|
||||||
|
#endif
|
||||||
|
return connect_failed_because_or_peer_2(err);
|
||||||
|
}
|
||||||
|
|
||||||
// Processes the socket until it's either ready, died, or would block
|
// Processes the socket until it's either ready, died, or would block
|
||||||
void socket_update(Socket *sock)
|
void socket_update(Socket *sock)
|
||||||
{
|
{
|
||||||
@@ -367,8 +403,8 @@ void socket_update(Socket *sock)
|
|||||||
again = true;
|
again = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0 && errno == EINPROGRESS) { // TODO: I'm pretty sure all the error numbers need to be changed for windows
|
if (connect_pending()) { // TODO: I'm pretty sure all the error numbers need to be changed for windows
|
||||||
// Connection pending
|
// Connection pending
|
||||||
sock->raw = raw;
|
sock->raw = raw;
|
||||||
sock->state = SOCKET_STATE_CONNECTING;
|
sock->state = SOCKET_STATE_CONNECTING;
|
||||||
@@ -379,7 +415,7 @@ void socket_update(Socket *sock)
|
|||||||
// Connect failed
|
// Connect failed
|
||||||
|
|
||||||
// If remote peer not working, try next address
|
// If remote peer not working, try next address
|
||||||
if (errno == ECONNREFUSED || errno == ETIMEDOUT || errno == ENETUNREACH || errno == EHOSTUNREACH) {
|
if (connect_failed_because_or_peer()) {
|
||||||
sock->state = SOCKET_STATE_PENDING;
|
sock->state = SOCKET_STATE_PENDING;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
again = true;
|
again = true;
|
||||||
@@ -402,7 +438,7 @@ void socket_update(Socket *sock)
|
|||||||
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
|
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
|
||||||
|
|
||||||
// If remote peer not working, try next address
|
// If remote peer not working, try next address
|
||||||
if (err == ECONNREFUSED || err == ETIMEDOUT || err == ENETUNREACH || err == EHOSTUNREACH) {
|
if (connect_failed_because_or_peer_2(err)) {
|
||||||
sock->state = SOCKET_STATE_PENDING;
|
sock->state = SOCKET_STATE_PENDING;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
again = true;
|
again = true;
|
||||||
@@ -592,6 +628,25 @@ void socket_update(Socket *sock)
|
|||||||
} while (again);
|
} while (again);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool would_block(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
return err == WSAEWOULDBLOCK;
|
||||||
|
#else
|
||||||
|
return errno == EAGAIN || errno == EWOULDBLOCK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool interrupted(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return errno == EINTR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int socket_read(Socket *sock, char *dst, int max)
|
int socket_read(Socket *sock, char *dst, int max)
|
||||||
{
|
{
|
||||||
// If not ESTABLISHED, set state to DIED and return
|
// If not ESTABLISHED, set state to DIED and return
|
||||||
@@ -608,11 +663,11 @@ int socket_read(Socket *sock, char *dst, int max)
|
|||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
} else {
|
} else {
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (would_block()) {
|
||||||
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
||||||
sock->events = POLLIN;
|
sock->events = POLLIN;
|
||||||
} else {
|
} else {
|
||||||
if (errno != EINTR) {
|
if (!interrupted()) {
|
||||||
sock->state = SOCKET_STATE_DIED;
|
sock->state = SOCKET_STATE_DIED;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
}
|
}
|
||||||
@@ -660,11 +715,11 @@ int socket_write(Socket *sock, char *src, int len)
|
|||||||
if (!socket_secure(sock)) {
|
if (!socket_secure(sock)) {
|
||||||
int ret = send(sock->raw, src, len, 0);
|
int ret = send(sock->raw, src, len, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (would_block()) {
|
||||||
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
sock->state = SOCKET_STATE_ESTABLISHED_WAIT;
|
||||||
sock->events = POLLOUT;
|
sock->events = POLLOUT;
|
||||||
} else {
|
} else {
|
||||||
if (errno != EINTR) {
|
if (!interrupted()) {
|
||||||
sock->state = SOCKET_STATE_DIED;
|
sock->state = SOCKET_STATE_DIED;
|
||||||
sock->events = 0;
|
sock->events = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user