[swrap] [PATCH] treat newfd correctly in dup2()

Michael Adam obnox at samba.org
Tue Aug 23 09:44:09 UTC 2016


Hi,

attached find a patch that fixes our treatment of 'newfd'
in swrap_dup2() that Metze and I wrote.

Anoop has written a test case for that (it fails without
the swrap patch). Thanks!

Review / push appreciated!

Michael
-------------- next part --------------
From 3cf712966ed06a067a11bbd5835781de625edd96 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 16 Aug 2016 10:59:40 +0200
Subject: [PATCH 1/2] swrap: treat the case of fd == newfd correctly in dup2()

Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 src/socket_wrapper.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 3dc80fa..6c4ae3b 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -5181,6 +5181,16 @@ static int swrap_dup2(int fd, int newfd)
 		return libc_dup2(fd, newfd);
 	}
 
+	if (fd == newfd) {
+		/*
+		 * According to the manpage:
+		 *
+		 * "If oldfd is a valid file descriptor, and newfd has the same
+		 * value as oldfd, then dup2() does nothing, and returns newfd."
+		 */
+		return newfd;
+	}
+
 	if (find_socket_info(newfd)) {
 		/* dup2() does an implicit close of newfd, which we
 		 * need to emulate */
-- 
2.5.5


From a89f5c7e7492b1fd67e74740800ff5ae3a8315b7 Mon Sep 17 00:00:00 2001
From: Anoop C S <anoopcs at redhat.com>
Date: Mon, 22 Aug 2016 19:37:47 +0530
Subject: [PATCH 2/2] swrap: Add test case to validate oldfd = newfd case in
 dup2()

Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
---
 tests/CMakeLists.txt  |  1 +
 tests/test_tcp_dup2.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 tests/test_tcp_dup2.c

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index aecf6b8..9b5c4bf 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -21,6 +21,7 @@ target_link_libraries(${TORTURE_LIBRARY}
 set(SWRAP_TESTS
     test_ioctl
     test_tcp_listen
+    test_tcp_dup2
     test_echo_tcp_socket
     test_echo_tcp_connect
     test_echo_tcp_bind
diff --git a/tests/test_tcp_dup2.c b/tests/test_tcp_dup2.c
new file mode 100644
index 0000000..fd6adc2
--- /dev/null
+++ b/tests/test_tcp_dup2.c
@@ -0,0 +1,50 @@
+#include "torture.h"
+
+#include <cmocka.h>
+#include <unistd.h>
+
+static int setup(void **state)
+{
+	torture_setup_socket_dir(state);
+
+	return 0;
+}
+
+static int teardown(void **state)
+{
+	torture_teardown_socket_dir(state);
+
+	return 0;
+}
+
+static void test_dup2_existing_open_fd(void **state)
+{
+	int s, dup_s;
+
+	(void) state; /* unused */
+
+	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	assert_int_not_equal(s, -1);
+
+	/*
+	 * Here we try to duplicate the existing socket fd to itself
+	 * and as per man page for dup2() it must return the already
+	 * open fd without any failure.
+	 */
+	dup_s = dup2(s, s);
+	assert_int_equal(dup_s, s);
+
+	close(s);
+}
+
+int main(void) {
+	int rc;
+
+	const struct CMUnitTest tcp_dup2_tests[] = {
+		cmocka_unit_test(test_dup2_existing_open_fd),
+	};
+
+	rc = cmocka_run_group_tests(tcp_dup2_tests, setup, teardown);
+
+	return rc;
+}
-- 
2.5.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20160823/866a3243/signature.sig>


More information about the samba-technical mailing list