diff options
author | Minun Dragonation <minun@mewmew.cn> | 2019-05-05 21:34:28 +0800 |
---|---|---|
committer | Minun Dragonation <minun@mewmew.cn> | 2019-05-05 21:34:28 +0800 |
commit | d8f814d48b25e202065b5a2b829cd0c2c20d29d3 (patch) | |
tree | 5e90f07dde80e12291c7b5e6c4147b433c104c4c | |
parent | f5f855c91239706b173e2412cea301f4a3643e2d (diff) |
fix bugs of setsockopt diff in win compact implementation
-rw-r--r-- | sockcompat.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sockcompat.c b/sockcompat.c index b52cbc6..047f8b6 100644 --- a/sockcompat.c +++ b/sockcompat.c @@ -189,13 +189,31 @@ 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))) { + struct timeval *tv = (struct timeval *)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; + *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 = (struct timeval *)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; } |