mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
a few cleanups and a fix for async connects
svn path=/trunk/net/; revision=5821
This commit is contained in:
parent
350c524cc8
commit
5574d519c9
110
src/net/sock.c
110
src/net/sock.c
@ -120,6 +120,15 @@ int sock_error(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sock_set_error(int val)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSASetLastError (val);
|
||||||
|
#else
|
||||||
|
errno = val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* sock_recoverable
|
/* sock_recoverable
|
||||||
**
|
**
|
||||||
** determines if the socket error is recoverable
|
** determines if the socket error is recoverable
|
||||||
@ -127,23 +136,43 @@ int sock_error(void)
|
|||||||
*/
|
*/
|
||||||
int sock_recoverable(int error)
|
int sock_recoverable(int error)
|
||||||
{
|
{
|
||||||
return (error == 0 || error == EAGAIN || error == EINTR ||
|
switch (error)
|
||||||
error == EINPROGRESS || error == EWOULDBLOCK);
|
{
|
||||||
|
case 0:
|
||||||
|
case EAGAIN:
|
||||||
|
case EINTR:
|
||||||
|
case EINPROGRESS:
|
||||||
|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
#endif
|
||||||
|
#ifdef ERESTART
|
||||||
|
case ERESTART:
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sock_stalled (int error)
|
int sock_stalled (int error)
|
||||||
{
|
{
|
||||||
return error == EAGAIN || error == EINPROGRESS || error == EWOULDBLOCK ||
|
switch (error)
|
||||||
error == EALREADY;
|
{
|
||||||
|
case EAGAIN:
|
||||||
|
case EINPROGRESS:
|
||||||
|
case EALREADY:
|
||||||
|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
#endif
|
||||||
|
#ifdef ERESTART
|
||||||
|
case ERESTART:
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* what is this??? */
|
|
||||||
static int sock_success (int error)
|
|
||||||
{
|
|
||||||
return error == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int sock_connect_pending (int error)
|
static int sock_connect_pending (int error)
|
||||||
{
|
{
|
||||||
@ -420,7 +449,7 @@ int sock_read_line(sock_t sock, char *buff, const int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* see if a connection can be written to
|
/* see if a connection can be written to
|
||||||
** return -1 unable to check
|
** return -1 for failure
|
||||||
** return 0 for not yet
|
** return 0 for not yet
|
||||||
** return 1 for ok
|
** return 1 for ok
|
||||||
*/
|
*/
|
||||||
@ -429,24 +458,33 @@ int sock_connected (int sock, unsigned timeout)
|
|||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
int val = SOCK_ERROR;
|
int val = SOCK_ERROR;
|
||||||
socklen_t size = sizeof val;
|
socklen_t size = sizeof val;
|
||||||
struct timeval tv;
|
struct timeval tv, *timeval = NULL;
|
||||||
|
|
||||||
tv.tv_sec = timeout;
|
if (timeout)
|
||||||
tv.tv_usec = 0;
|
{
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
timeval = &tv;
|
||||||
|
}
|
||||||
|
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
FD_SET(sock, &wfds);
|
FD_SET(sock, &wfds);
|
||||||
|
|
||||||
switch (select(sock + 1, NULL, &wfds, NULL, &tv))
|
switch (select(sock + 1, NULL, &wfds, NULL, timeval))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return SOCK_TIMEOUT;
|
return SOCK_TIMEOUT;
|
||||||
default:
|
default:
|
||||||
/* on windows getsockopt.val is defined as char* */
|
/* on windows getsockopt.val is defined as char* */
|
||||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) < 0)
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0)
|
||||||
val = SOCK_ERROR;
|
{
|
||||||
|
if (val == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case -1:
|
case -1:
|
||||||
return val;
|
if (sock_recoverable (sock_error()))
|
||||||
|
return 0;
|
||||||
|
return SOCK_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,31 +546,37 @@ sock_t sock_connect_wto(const char *hostname, const int port, const int timeout)
|
|||||||
ai = head;
|
ai = head;
|
||||||
while (ai)
|
while (ai)
|
||||||
{
|
{
|
||||||
if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) > -1)
|
if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) >= 0)
|
||||||
{
|
{
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
|
||||||
sock_set_blocking (sock, SOCK_NONBLOCK);
|
sock_set_blocking (sock, SOCK_NONBLOCK);
|
||||||
if (connect (sock, ai->ai_addr, ai->ai_addrlen) < 0)
|
|
||||||
|
if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* loop as the connect maybe async */
|
||||||
|
while (sock != SOCK_ERROR)
|
||||||
|
{
|
||||||
|
if (sock_recoverable (sock_error()))
|
||||||
{
|
{
|
||||||
if (sock_connected (sock, timeout) > 0)
|
if (sock_connected (sock, timeout) > 0)
|
||||||
{
|
{
|
||||||
sock_set_blocking(sock, SOCK_BLOCK);
|
if (timeout) /* really wants to reset to what it was before */
|
||||||
|
sock_set_blocking(sock, SOCK_BLOCK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
sock_close (sock);
|
||||||
|
sock = SOCK_ERROR;
|
||||||
}
|
}
|
||||||
else
|
if (sock != SOCK_ERROR)
|
||||||
{
|
break;
|
||||||
if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sock_close (sock);
|
|
||||||
}
|
}
|
||||||
sock = SOCK_ERROR;
|
|
||||||
ai = ai->ai_next;
|
ai = ai->ai_next;
|
||||||
}
|
}
|
||||||
if (head) freeaddrinfo (head);
|
if (head)
|
||||||
|
freeaddrinfo (head);
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user