浏览代码

Merged from trunk

2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>

	Removed test file
	* test/CookieStorageTest.cc

2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>

	Check both EAGAIN and EWOULDBLOCK
	* src/SocketCore.cc

2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>

	Removed ret == 0 checking for SSL_read(), SSL_write() and
	SSL_peek() because the checks are done in the caller.  In
	SocketBuffer::send(), throw exception if nothing could be written
	and socket error was not EWOULDBLOCK
	* src/SocketBuffer.cc
	* src/SocketCore.cc

2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>

	Fixed error code handling so that it can handle Winsock2 error
	code.
	* src/SocketCore.cc
	* src/SocketCore.h
Tatsuhiro Tsujikawa 16 年之前
父节点
当前提交
f554d27648
共有 5 个文件被更改,包括 98 次插入77 次删除
  1. 26 0
      ChangeLog
  2. 9 1
      src/SocketBuffer.cc
  3. 60 69
      src/SocketCore.cc
  4. 0 4
      src/SocketCore.h
  5. 3 3
      test/CookieStorageTest.cc

+ 26 - 0
ChangeLog

@@ -1,3 +1,29 @@
+2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Removed test file
+	* test/CookieStorageTest.cc
+
+2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Check both EAGAIN and EWOULDBLOCK
+	* src/SocketCore.cc
+
+2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Removed ret == 0 checking for SSL_read(), SSL_write() and
+	SSL_peek() because the checks are done in the caller.  In
+	SocketBuffer::send(), throw exception if nothing could be written
+	and socket error was not EWOULDBLOCK
+	* src/SocketBuffer.cc
+	* src/SocketCore.cc
+
+2010-02-15  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Fixed error code handling so that it can handle Winsock2 error
+	code.
+	* src/SocketCore.cc
+	* src/SocketCore.h
+
 2010-02-14  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Bump up version number to 1.8.3

+ 9 - 1
src/SocketBuffer.cc

@@ -33,9 +33,14 @@
  */
 /* copyright --> */
 #include "SocketBuffer.h"
-#include "SocketCore.h"
+
 #include <cassert>
 
+#include "SocketCore.h"
+#include "DlAbortEx.h"
+#include "message.h"
+#include "StringFormat.h"
+
 namespace aria2 {
 
 SocketBuffer::SocketBuffer(const SharedHandle<SocketCore>& socket):
@@ -61,6 +66,9 @@ ssize_t SocketBuffer::send()
   }
   ssize_t len = _socket->writeData(_sendbuf.c_str(),
                                    _sendbuf.size());
+  if(len == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
+    throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, "Connection closed.").str());
+  }
   _sendbuf.erase(0, len);
   return len;
 }

+ 60 - 69
src/SocketCore.cc

@@ -59,6 +59,8 @@
 # include "TLSContext.h"
 #endif // ENABLE_SSL
 
+namespace aria2 {
+
 #ifndef __MINGW32__
 # define SOCKET_ERRNO (errno)
 #else
@@ -67,9 +69,18 @@
 
 #ifdef __MINGW32__
 # define A2_EINPROGRESS WSAEWOULDBLOCK
-#else
+# define A2_EWOULDBLOCK WSAEWOULDBLOCK
+# define A2_EINTR WSAEINTR
+# define A2_WOULDBLOCK(e) (e == WSAEWOULDBLOCK)
+#else // !__MINGW32__
 # define A2_EINPROGRESS EINPROGRESS
-#endif // __MINGW32__
+# ifndef EWOULDBLOCK
+#  define EWOULDBLOCK EAGAIN
+# endif // EWOULDBLOCK
+# define A2_EWOULDBLOCK EWOULDBLOCK
+# define A2_EINTR EINTR
+# define A2_WOULDBLOCK(e) (e == EWOULDBLOCK || e == EAGAIN)
+#endif // !__MINGW32__
 
 #ifdef __MINGW32__
 # define CLOSE(X) ::closesocket(X)
@@ -77,7 +88,32 @@
 # define CLOSE(X) while(close(X) == -1 && errno == EINTR)
 #endif // __MINGW32__
 
-namespace aria2 {
+static const char *errorMsg(const int err)
+{
+#ifndef __MINGW32__
+  return strerror(err);
+#else
+  static char buf[256];
+  if (FormatMessage(
+                    FORMAT_MESSAGE_FROM_SYSTEM |
+                    FORMAT_MESSAGE_IGNORE_INSERTS,
+                    NULL,
+                    err,
+                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                    (LPTSTR) &buf,
+                    sizeof(buf),
+                    NULL
+                    ) == 0) {
+    snprintf(buf, sizeof(buf), EX_SOCKET_UNKNOWN_ERROR, err, err);
+  }
+  return buf;
+#endif // __MINGW32__
+}
+
+static const char *errorMsg()
+{
+  return errorMsg(SOCKET_ERRNO);
+}
 
 #ifdef HAVE_EPOLL
 SocketCore::PollMethod SocketCore::_pollMethod = SocketCore::POLL_METHOD_EPOLL;
@@ -181,7 +217,7 @@ static sock_t bindInternal(int family, int socktype, int protocol,
   }
   if(::bind(fd, addr, addrlen) == -1) {
     if(LogFactory::getInstance()->debug()) {
-      LogFactory::getInstance()->debug(EX_SOCKET_BIND, strerror(errno));
+      LogFactory::getInstance()->debug(EX_SOCKET_BIND, errorMsg());
     }
     CLOSE(fd);
     return -1;
@@ -209,7 +245,7 @@ static sock_t bindTo
       return fd;
     }
   }
-  error = strerror(errno);
+  error = errorMsg();
   return -1;
 }
 
@@ -255,7 +291,7 @@ void SocketCore::bind(const struct sockaddr* addr, socklen_t addrlen)
   if(fd != (sock_t)-1) {
     sockfd = fd;
   } else {
-    throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, strerror(errno)).str());
+    throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, errorMsg()).str());
   }
 }
 
@@ -271,7 +307,7 @@ SocketCore* SocketCore::acceptConnection() const
   struct sockaddr_storage sockaddr;
   socklen_t len = sizeof(sockaddr);
   sock_t fd;
-  while((fd = accept(sockfd, reinterpret_cast<struct sockaddr*>(&sockaddr), &len)) == (sock_t) -1 && SOCKET_ERRNO == EINTR);
+  while((fd = accept(sockfd, reinterpret_cast<struct sockaddr*>(&sockaddr), &len)) == (sock_t) -1 && SOCKET_ERRNO == A2_EINTR);
   if(fd == (sock_t) -1) {
     throw DL_ABORT_EX(StringFormat(EX_SOCKET_ACCEPT, errorMsg()).str());
   }
@@ -331,7 +367,7 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
         if(::bind(fd,reinterpret_cast<const struct sockaddr*>(&(*i).first),
                   (*i).second) == -1) {
           if(LogFactory::getInstance()->debug()) {
-            LogFactory::getInstance()->debug(EX_SOCKET_BIND, strerror(errno));
+            LogFactory::getInstance()->debug(EX_SOCKET_BIND, errorMsg());
           }
         } else {
           bindSuccess = true;
@@ -359,7 +395,7 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
   }
   if(sockfd == (sock_t) -1) {
     throw DL_ABORT_EX(StringFormat(EX_SOCKET_CONNECT, host.c_str(),
-                                   strerror(errno)).str());
+                                   errorMsg()).str());
   }
 }
 
@@ -479,7 +515,7 @@ bool SocketCore::isWritable(time_t timeout)
         // time out
         return false;
       } else {
-        if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == EINTR) {
+        if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
           return false;
         } else {
           throw DL_RETRY_EX(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
@@ -532,7 +568,7 @@ bool SocketCore::isReadable(time_t timeout)
         // time out
         return false;
       } else {
-        if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == EINTR) {
+        if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
           return false;
         } else {
           throw DL_RETRY_EX(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
@@ -578,9 +614,9 @@ ssize_t SocketCore::writeData(const char* data, size_t len)
   _wantWrite = false;
 
   if(!secure) {
-    while((ret = send(sockfd, data, len, 0)) == -1 && SOCKET_ERRNO == EINTR);
+    while((ret = send(sockfd, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
     if(ret == -1) {
-      if(SOCKET_ERRNO == EAGAIN) {
+      if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
         _wantWrite = true;
         ret = 0;
       } else {
@@ -590,11 +626,6 @@ ssize_t SocketCore::writeData(const char* data, size_t len)
   } else {
 #ifdef HAVE_LIBSSL
     ret = SSL_write(ssl, data, len);
-    if(ret == 0) {
-      throw DL_RETRY_EX
-        (StringFormat
-         (EX_SOCKET_SEND, ERR_error_string(SSL_get_error(ssl, ret), 0)).str());
-    }
     if(ret < 0) {
       ret = sslHandleEAGAIN(ret);
     }
@@ -626,10 +657,10 @@ void SocketCore::readData(char* data, size_t& len)
   _wantWrite = false;
 
   if(!secure) {    
-    while((ret = recv(sockfd, data, len, 0)) == -1 && SOCKET_ERRNO == EINTR);
+    while((ret = recv(sockfd, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
     
     if(ret == -1) {
-      if(SOCKET_ERRNO == EAGAIN) {
+      if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
         _wantRead = true;
         ret = 0;
       } else {
@@ -641,11 +672,6 @@ void SocketCore::readData(char* data, size_t& len)
     // for SSL
     // TODO handling len == 0 case required
     ret = SSL_read(ssl, data, len);
-    if(ret == 0) {
-      throw DL_RETRY_EX
-        (StringFormat
-         (EX_SOCKET_RECV, ERR_error_string(SSL_get_error(ssl, ret), 0)).str());
-    }
     if(ret < 0) {
       ret = sslHandleEAGAIN(ret);
     }
@@ -677,9 +703,10 @@ void SocketCore::peekData(char* data, size_t& len)
   _wantWrite = false;
 
   if(!secure) {
-    while((ret = recv(sockfd, data, len, MSG_PEEK)) == -1 && SOCKET_ERRNO == EINTR);
+    while((ret = recv(sockfd, data, len, MSG_PEEK)) == -1 &&
+          SOCKET_ERRNO == A2_EINTR);
     if(ret == -1) {
-      if(SOCKET_ERRNO == EAGAIN) {
+      if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
         _wantRead = true;
         ret = 0;
       } else {
@@ -691,11 +718,6 @@ void SocketCore::peekData(char* data, size_t& len)
     // for SSL
     // TODO handling len == 0 case required
     ret = SSL_peek(ssl, data, len);
-    if(ret == 0) {
-      throw DL_RETRY_EX
-        (StringFormat(EX_SOCKET_PEEK,
-                      ERR_error_string(SSL_get_error(ssl, ret), 0)).str());
-    }
     if(ret < 0) {
       ret = sslHandleEAGAIN(ret);
     }
@@ -1014,38 +1036,6 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname)
   }
 }
 
-/* static */ int SocketCore::error()
-{
-  return SOCKET_ERRNO;
-}
-
-/* static */ const char *SocketCore::errorMsg()
-{
-  return errorMsg(SOCKET_ERRNO);
-}
-
-/* static */ const char *SocketCore::errorMsg(const int err)
-{
-#ifndef __MINGW32__
-  return strerror(err);
-#else
-  static char buf[256];
-  if (FormatMessage(
-                    FORMAT_MESSAGE_FROM_SYSTEM |
-                    FORMAT_MESSAGE_IGNORE_INSERTS,
-                    NULL,
-                    err,
-                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-                    (LPTSTR) &buf,
-                    sizeof(buf),
-                    NULL
-                    ) == 0) {
-    snprintf(buf, sizeof(buf), EX_SOCKET_UNKNOWN_ERROR, err, err);
-  }
-  return buf;
-#endif // __MINGW32__
-}
-
 ssize_t SocketCore::writeData(const char* data, size_t len,
                               const std::string& host, uint16_t port)
 {
@@ -1063,11 +1053,12 @@ ssize_t SocketCore::writeData(const char* data, size_t len,
   struct addrinfo* rp;
   ssize_t r = -1;
   for(rp = res; rp; rp = rp->ai_next) {
-    while((r = sendto(sockfd, data, len, 0, rp->ai_addr, rp->ai_addrlen)) == -1 && EINTR == SOCKET_ERRNO);
+    while((r = sendto(sockfd, data, len, 0, rp->ai_addr, rp->ai_addrlen)) == -1
+          && A2_EINTR == SOCKET_ERRNO);
     if(r == static_cast<ssize_t>(len)) {
       break;
     }
-    if(r == -1 && SOCKET_ERRNO == EAGAIN) {
+    if(r == -1 && A2_WOULDBLOCK(SOCKET_ERRNO)) {
       _wantWrite = true;
       r = 0;
       break;
@@ -1090,9 +1081,9 @@ ssize_t SocketCore::readDataFrom(char* data, size_t len,
   struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
   ssize_t r;
   while((r = recvfrom(sockfd, data, len, 0, addrp, &sockaddrlen)) == -1 &&
-        EINTR == SOCKET_ERRNO);
+        A2_EINTR == SOCKET_ERRNO);
   if(r == -1) {
-    if(SOCKET_ERRNO == EAGAIN) {
+    if(A2_WOULDBLOCK(SOCKET_ERRNO)) {
       _wantRead = true;
       r = 0;
     } else {
@@ -1155,7 +1146,7 @@ void SocketCore::bindAddress(const std::string& iface)
   if(getifaddrs(&ifaddr) == -1) {
     throw DL_ABORT_EX
       (StringFormat(MSG_INTERFACE_NOT_FOUND,
-                    iface.c_str(), strerror(errno)).str());
+                    iface.c_str(), errorMsg()).str());
   } else {
     auto_delete<struct ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs);
     for(struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) {

+ 0 - 4
src/SocketCore.h

@@ -136,10 +136,6 @@ private:
 #endif // HAVE_EPOLL
 
   SocketCore(sock_t sockfd, int sockType);
-
-  static int error();
-  static const char *errorMsg();
-  static const char *errorMsg(const int err);
 public:
   SocketCore(int sockType = SOCK_STREAM);
   ~SocketCore();

+ 3 - 3
test/CookieStorageTest.cc

@@ -348,9 +348,9 @@ void CookieStorageTest::testSaveNsFormat_fail()
 {
   std::string filename = "/tmp/aria2_CookieStorageTest_testSaveNsFormat_fail";
   File f(filename);
-  if(!f.exists()) {
-    f.mkdirs();
-  }
+  f.remove();
+  f.mkdirs();
+  CPPUNIT_ASSERT(f.isDir());
   CookieStorage st;
   CPPUNIT_ASSERT(!st.saveNsFormat(filename));
 }