patch-libapp_sock_cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. $OpenBSD: patch-libapp_sock_cpp,v 1.1 2015/07/01 11:33:50 bluhm Exp $
  2. --- libapp/sock.cpp.orig Thu Feb 8 00:45:57 2001
  3. +++ libapp/sock.cpp Tue Nov 11 20:08:05 2014
  4. @@ -48,9 +48,9 @@ int inet_aton( const char* cp, struct in_addr* inp )
  5. static void socket_nonblock( sockobj_t sock )
  6. {
  7. int tmp;
  8. - fcntl( sock, F_GETFL, &tmp );
  9. + tmp = fcntl( sock, F_GETFL);
  10. tmp |= O_NONBLOCK;
  11. - fcntl( sock, F_SETFL, &tmp );
  12. + fcntl( sock, F_SETFL, tmp );
  13. }
  14. #endif
  15. #if defined(_WIN32)
  16. @@ -75,6 +75,7 @@ static void socket_reuseaddr( sockobj_t sock )
  17. CInetAddr::CInetAddr( void )
  18. {
  19. + memset(&m_addr, 0, sizeof(m_addr));
  20. m_addr.sin_family = AF_INET;
  21. m_addr.sin_addr.s_addr = INADDR_NONE;
  22. m_addr.sin_port = 0;
  23. @@ -82,6 +83,7 @@ CInetAddr::CInetAddr( void )
  24. CInetAddr::CInetAddr( const in_addr& host )
  25. {
  26. + memset(&m_addr, 0, sizeof(m_addr));
  27. m_addr.sin_family = AF_INET;
  28. m_addr.sin_addr = host;
  29. m_addr.sin_port = 0;
  30. @@ -319,18 +321,74 @@ size_t CSocket::Write( CPVOID pbuf, size_t nLen )
  31. {
  32. assert_or_retv( 0, (pbuf != NULL && IsOpen()) );
  33. - m_err = SOCKERR_NONE;
  34. - ssize_t n = send( m_sock, (const char*)pbuf, nLen, 0 );
  35. - if( n == SOCKET_ERROR )
  36. + fd_set writefds;
  37. + FD_ZERO(&writefds);
  38. + FD_SET(m_sock,&writefds);
  39. +
  40. + int retries = 3;
  41. + int readyfds = 0;
  42. + int offset = 0;
  43. + int len = nLen;
  44. + ssize_t n = 0;
  45. + timeval timer;
  46. + timer.tv_sec = 1;
  47. + timer.tv_usec = 0;
  48. +
  49. + // XXX Fix for the problem with incomplete writes to socket
  50. + while( FD_ISSET(m_sock,&writefds) && len > 0 )
  51. {
  52. - n = 0;
  53. - m_err = SOCK_LAST_ERROR();
  54. - if( m_err != SOCKERR_WOULDBLOCK )
  55. - {
  56. - n = SOCKERR_EOF;
  57. - }
  58. - }
  59. + readyfds = select(m_sock+1, NULL, &writefds, NULL, &timer);
  60. + // Fehler
  61. + if ( readyfds < 0 )
  62. + {
  63. + if ( errno != EINTR )
  64. + {
  65. + dbgout("Problem while writing data to socket: %s", strerror(errno));
  66. + return 0;
  67. + }
  68. + }
  69. + // Kein Socket bereit
  70. + if ( readyfds == 0 )
  71. + {
  72. + if ( !FD_ISSET(m_sock, &writefds) )
  73. + retries--;
  74. + if ( !retries )
  75. + {
  76. + dbgout("Timeout while writing to socket");
  77. + return 0;
  78. + }
  79. + }
  80. + // Socket bereit, nun wird geschrieben
  81. + else
  82. + {
  83. + m_err = 0;
  84. + n = send( m_sock, (const char*)pbuf+offset, len, 0 );
  85. + // Fehler?
  86. + if( n == -1 )
  87. + {
  88. + //XXX DEBUG
  89. + dbgout("CSocket::Write: Error %s (%i) occured", strerror(errno), errno);
  90. + n = 0;
  91. + m_err = errno;
  92. + if( m_err != EAGAIN )
  93. + {
  94. + n = SOCKERR_EOF;
  95. + }
  96. + break;
  97. + }
  98. + // Daten nicht komplett geschrieben
  99. + else if ( n < len )
  100. + {
  101. + len = len - n;
  102. + offset += n;
  103. + }
  104. + // Daten komplett, dann raus aus der Schleife
  105. + else {
  106. + break;
  107. + }
  108. + }
  109. + }
  110. return n;
  111. }