From: Michal 'vorner' Vaner Date: Fri, 6 Jan 2012 14:46:36 +0000 (+0100) Subject: [805] Abort when can't send or close X-Git-Tag: trac2351_base~304^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ca3cc561237dde1fac32c592056051eb339bea03;p=thirdparty%2Fkea.git [805] Abort when can't send or close --- diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc index c33d9c3445..523cbfb7ca 100644 --- a/src/bin/sockcreator/sockcreator.cc +++ b/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) { diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h index ddf9a090d7..bbac27aa19 100644 --- a/src/bin/sockcreator/sockcreator.h +++ b/src/bin/sockcreator/sockcreator.h @@ -27,6 +27,7 @@ #include #include +#include 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 } diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc index 58f9217e7e..7593061192 100644 --- a/src/bin/sockcreator/tests/sockcreator_tests.cc +++ b/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); +} + }