summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nunberg <mnunberg@users.noreply.github.com>2019-08-09 03:52:06 -0400
committerGitHub <noreply@github.com>2019-08-09 03:52:06 -0400
commitfe215464caf1e11a34de06ec23576b01417397c7 (patch)
treebb6f8f7a579a44f82925bfb9098ef12d4df185e5
parentb1fa77d02330045ab5865cd6505f0863882f2656 (diff)
parent76394f1be87359c88b13fc327f86da9e949ce3e3 (diff)
Merge pull request #662 from dragonation/master
The setsockopt and getsockopt API diffs from BSD socket and WSA one
-rw-r--r--sockcompat.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/sockcompat.c b/sockcompat.c
index b52cbc6..4cc2f41 100644
--- a/sockcompat.c
+++ b/sockcompat.c
@@ -189,13 +189,35 @@ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen)
}
int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) {
- int ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
+ int ret = 0;
+ if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
+ if (*optlen >= sizeof (struct timeval)) {
+ struct timeval *tv = optval;
+ DWORD timeout = 0;
+ socklen_t dwlen = 0;
+ ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen);
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout * 1000) % 1000000;
+ } else {
+ ret = WSAEFAULT;
+ }
+ *optlen = sizeof (struct timeval);
+ } else {
+ ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
+ }
_updateErrno(ret != SOCKET_ERROR);
return ret != SOCKET_ERROR ? ret : -1;
}
int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) {
- int ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen);
+ int ret = 0;
+ if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
+ struct timeval *tv = optval;
+ DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD));
+ } else {
+ ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen);
+ }
_updateErrno(ret != SOCKET_ERROR);
return ret != SOCKET_ERROR ? ret : -1;
}