aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/drivers/common/inet_drv.c
diff options
context:
space:
mode:
authorPatrik Nyblom <[email protected]>2013-01-23 15:59:44 +0100
committerPatrik Nyblom <[email protected]>2013-01-23 15:59:44 +0100
commit13735fd978b94225c7c3285c763314f6d2d5d736 (patch)
tree3153e1033dd2a79be2f2187d113cf0ca51e00326 /erts/emulator/drivers/common/inet_drv.c
parentdb4c3dbd2202ea27a91e97068f09e914522a042b (diff)
parentace7f0a1593e27d657ece6049844bf71935b24c0 (diff)
downloadotp-13735fd978b94225c7c3285c763314f6d2d5d736.tar.gz
otp-13735fd978b94225c7c3285c763314f6d2d5d736.tar.bz2
otp-13735fd978b94225c7c3285c763314f6d2d5d736.zip
Merge branch 'pan/R16/redhat_workaround'
* pan/R16/redhat_workaround: Clean up and make the fix work on windows. Add workaround for CentOS/RedHat writev bug to inet_drv OTP-10747
Diffstat (limited to 'erts/emulator/drivers/common/inet_drv.c')
-rw-r--r--erts/emulator/drivers/common/inet_drv.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 236b8710fb..5f8837fd4f 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -9723,6 +9723,7 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
DEBUGF(("tcp_inet_output(%ld): s=%d, About to send %d items\r\n",
(long)desc->inet.port, desc->inet.s, vsize));
if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, iov, vsize, &n, 0))) {
+ write_error:
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
DEBUGF(("tcp_inet_output(%ld): sock_sendv(%d) errno = %d\r\n",
(long)desc->inet.port, vsize, sock_errno()));
@@ -9733,6 +9734,22 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
desc->inet.send_would_block = 1;
#endif
goto done;
+ } else if (n == 0) { /* Workaround for redhat/CentOS 6.3 returning
+ 0 when sending packets with
+ sizes > (max 32 bit signed int) */
+ size_t howmuch = 0x7FFFFFFF; /* max signed 32 bit */
+ int x;
+ for(x = 0; x < vsize && iov[x].iov_len == 0; ++x)
+ ;
+ if (x < vsize) {
+ if (howmuch > iov[x].iov_len) {
+ howmuch = iov[x].iov_len;
+ }
+ n = sock_send(desc->inet.s, iov[x].iov_base,howmuch,0);
+ if (IS_SOCKET_ERROR(n)) {
+ goto write_error;
+ }
+ }
}
if (driver_deq(ix, n) <= desc->low) {
if (IS_BUSY(INETP(desc))) {