Browse Source

[805] Abort when can't send or close

Michal 'vorner' Vaner 13 years ago
parent
commit
ca3cc56123

+ 7 - 3
src/bin/sockcreator/sockcreator.cc

@@ -70,7 +70,7 @@ get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len)
 
 int
 run(const int input_fd, const int output_fd, const get_sock_t get_sock,
-    const send_fd_t send_fd)
+    const send_fd_t send_fd, const close_t close)
 {
     for (;;) {
         // Read the command
@@ -131,9 +131,13 @@ run(const int input_fd, const int output_fd, const get_sock_t get_sock,
                 if (result >= 0) { // We got the socket
                     WRITE("S", 1);
                     // FIXME: Check the output and write a test for it
-                    send_fd(output_fd, result);
+                    if(send_fd(output_fd, result) == FD_SYSTEM_ERROR) {
+                        return 3;
+                    }
                     // Don't leak the socket
-                    close(result);
+                    if (close(result) == -1) {
+                        return 4;
+                    }
                 } else {
                     WRITE("E", 1);
                     switch (result) {

+ 10 - 1
src/bin/sockcreator/sockcreator.h

@@ -27,6 +27,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <unistd.h>
 
 namespace isc {
 namespace socket_creator {
@@ -62,6 +63,11 @@ typedef
 int
 (*send_fd_t)(const int, const int);
 
+/// \brief Type of the close() function, so it can be passed as a parameter.
+typedef
+int
+(*close_t)(int);
+
 /**
  * \short Infinite loop parsing commands and returning the sockets.
  *
@@ -88,11 +94,14 @@ int
  * \param send_fd_fun The function that is used to send the socket over
  *     a file descriptor. This should be left on the default value, it is
  *     here for testing purposes.
+ * \param close The close function used to close sockets, coming from
+ *     unistd.h. It can be overriden in tests.
  */
 int
 run(const int input_fd, const int output_fd,
     const get_sock_t get_sock_fun = get_sock,
-    const send_fd_t send_fd_fun = isc::util::io::send_fd);
+    const send_fd_t send_fd_fun = isc::util::io::send_fd,
+    const close_t close = close);
 
 } // End of the namespaces
 }

+ 30 - 2
src/bin/sockcreator/tests/sockcreator_tests.cc

@@ -199,6 +199,12 @@ send_fd_dummy(const int destination, const int what)
     }
 }
 
+// Just ignore the fd and pretend success. We close invalid fds in the tests.
+int
+close_ignore(int) {
+    return (0);
+}
+
 /*
  * Generic test that it works, with various inputs and outputs.
  * It uses different functions to create the socket and send it and pass
@@ -207,7 +213,8 @@ send_fd_dummy(const int destination, const int what)
  */
 void run_test(const char *input_data, const size_t input_size,
     const char *output_data, const size_t output_size,
-    bool should_succeed = true)
+    bool should_succeed = true, const close_t test_close = close_ignore,
+    const send_fd_t send_fd = send_fd_dummy)
 {
     // Prepare the input feeder and output checker processes
     int input_fd(0), output_fd(0);
@@ -216,7 +223,7 @@ void run_test(const char *input_data, const size_t input_size,
     ASSERT_NE(-1, input) << "Couldn't start input feeder";
     ASSERT_NE(-1, output) << "Couldn't start output checker";
     // Run the body
-    int result(run(input_fd, output_fd, get_sock_dummy, send_fd_dummy));
+    int result(run(input_fd, output_fd, get_sock_dummy, send_fd, test_close));
     // Close the pipes
     close(input_fd);
     close(output_fd);
@@ -279,4 +286,25 @@ TEST(run, bad_sockets) {
         result, result_len);
 }
 
+// A close that fails
+int
+close_fail(int) {
+    return (-1);
+}
+
+TEST(run, cant_close) {
+    run_test("SU4\xff\xff\0\0\0\0", // This has 9 bytes
+             9, "S\x07", 2, false, close_fail);
+}
+
+int
+send_fd_fail(const int, const int) {
+    return (FD_SYSTEM_ERROR);
+}
+
+TEST(run, cant_send_fd) {
+    run_test("SU4\xff\xff\0\0\0\0", // This has 9 bytes
+             9, "S", 1, false, close_ignore, send_fd_fail);
+}
+
 }