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
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) {
#include <sys/types.h>
#include <sys/socket.h>
+#include <unistd.h>
namespace isc {
namespace socket_creator {
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.
*
* \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
}
}
}
+// 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
*/
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);
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);
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);
+}
+
}