Browse Source

[2916] catch invalid FD

JINMEI Tatuya 12 years ago
parent
commit
e43764fda3
2 changed files with 31 additions and 5 deletions
  1. 22 5
      src/lib/asiolink/local_socket.cc
  2. 9 0
      src/lib/asiolink/tests/local_socket_unittest.cc

+ 22 - 5
src/lib/asiolink/local_socket.cc

@@ -14,6 +14,7 @@
 
 #include <asiolink/local_socket.h>
 #include <asiolink/io_service.h>
+#include <asiolink/io_error.h>
 
 #include <asio.hpp>
 
@@ -24,13 +25,21 @@
 
 namespace isc {
 namespace asiolink {
-
 class LocalSocket::Impl {
 public:
     Impl(IOService& io_service, int fd) :
-        asio_sock_(io_service.get_io_service())
+        asio_sock_(io_service.get_io_service(),
+                   asio::local::stream_protocol(), fd)
     {
-        asio_sock_.assign(asio::local::stream_protocol(), fd, ec_);
+        // Depending on the underlying demultiplex API, the constructor may or
+        // may not throw in case fd is invalid.  To catch such cases sooner,
+        // we try to get the local endpoint (we don't need it in the rest of
+        // this implementation).
+        asio_sock_.local_endpoint(ec_);
+        if (ec_) {
+            isc_throw(IOError, "failed to open local socket with FD " << fd
+                      << " (local endpoint unknown): " << ec_.message());
+        }
     }
 
     void readCompleted(const asio::error_code& ec, ReadCallback user_callback);
@@ -51,8 +60,16 @@ LocalSocket::Impl::readCompleted(const asio::error_code& ec,
 }
 
 LocalSocket::LocalSocket(IOService& io_service, int fd) :
-    impl_(new Impl(io_service, fd))
-{}
+    impl_(NULL)
+{
+    try {
+        impl_ = new Impl(io_service, fd);
+    } catch (const asio::error_code& error) {
+        // Catch and convert any exception from asio's constructor
+        isc_throw(IOError, "failed to open local socket with FD " << fd
+                  << ": " << error.message());
+    }
+}
 
 LocalSocket::~LocalSocket() {
     delete impl_;

+ 9 - 0
src/lib/asiolink/tests/local_socket_unittest.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <asiolink/local_socket.h>
+#include <asiolink/io_error.h>
 
 #include <gtest/gtest.h>
 
@@ -103,6 +104,14 @@ TEST_F(LocalSocketTest, construct) {
     EXPECT_EQ(AF_UNIX, sock.getProtocol());
 }
 
+TEST_F(LocalSocketTest, constructError) {
+    // try to construct a LocalSocket object with a closed socket.  It should
+    // fail.
+    const int fd = sock_pair_[0].release();
+    EXPECT_EQ(0, close(fd));
+    EXPECT_THROW(LocalSocket(io_service_, fd), IOError);
+}
+
 TEST_F(LocalSocketTest, autoClose) {
     // Confirm that passed FD will be closed on destruction of LocalSocket
     const int fd = sock_pair_[0].release();