[SCM] Socket Wrapper Repository - branch master updated

Andreas Schneider asn at samba.org
Tue Aug 11 15:30:27 UTC 2015


The branch, master has been updated
       via  6ece682 swrap: Add enviornment variable to specify mtu size
       via  c2d26a8 tests: Add tcp sendmsg/recvmsg test
       via  32f65ea swrap: Fix TCP support with sendmsg/recvmsg
       via  2e7cda5 tests: Tests for msg_name(len) in sendmsg/revcmsg
       via  73c2168 tests: Fix testname of sendmsg tests
       via  85b7f56 swrap: Correctly update the msg_name in recvmsg()
       via  055eb78 tests: Migrate to new cmocka API
      from  00eb315 Update TODO

https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6ece682ee36794aebd08503c60ecb1797c04849f
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Aug 11 12:11:16 2015 +0200

    swrap: Add enviornment variable to specify mtu size
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit c2d26a8dbd89d3db32461061e0b33df4f3eb87a1
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Aug 11 11:40:30 2015 +0200

    tests: Add tcp sendmsg/recvmsg test
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 32f65eaa9ad699898fa274ea1f29655e6a344fb9
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Aug 11 11:39:52 2015 +0200

    swrap: Fix TCP support with sendmsg/recvmsg
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 2e7cda5246b3b7565d376e9609b0e84b3cdff1d5
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Mon Aug 10 16:09:16 2015 +0200

    tests: Tests for msg_name(len) in sendmsg/revcmsg
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 73c2168291825fcbff4a4846a395793ceac46202
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Mon Aug 10 13:39:09 2015 +0200

    tests: Fix testname of sendmsg tests
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 85b7f564bd397e82cf847607f0bcee4e35f489ac
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Aug 5 15:02:49 2015 +0200

    swrap: Correctly update the msg_name in recvmsg()
    
    This has been found while debugging nsupdate.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 055eb78f3690008021e17da8714da9db5247308c
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Aug 6 16:08:32 2015 +0200

    tests: Migrate to new cmocka API
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 doc/socket_wrapper.1                     |  11 +-
 doc/socket_wrapper.1.txt                 |   9 +-
 src/socket_wrapper.c                     | 114 ++++++++++---
 tests/CMakeLists.txt                     |   1 +
 tests/test_echo_tcp_bind.c               |  30 ++--
 tests/test_echo_tcp_connect.c            |  18 +-
 tests/test_echo_tcp_get_peer_sock_name.c |  44 ++---
 tests/test_echo_tcp_sendmsg_recvmsg.c    | 273 +++++++++++++++++++++++++++++++
 tests/test_echo_tcp_socket.c             |   8 +-
 tests/test_echo_tcp_socket_options.c     |  40 +++--
 tests/test_echo_tcp_write_read.c         |  24 ++-
 tests/test_echo_tcp_writev_readv.c       |  24 ++-
 tests/test_echo_udp_send_recv.c          |  24 ++-
 tests/test_echo_udp_sendmsg_recvmsg.c    | 224 ++++++++++++++++++++++++-
 tests/test_echo_udp_sendto_recvfrom.c    |  24 ++-
 tests/test_ioctl.c                       |  18 +-
 tests/test_sendmsg_recvmsg_fd.c          |   6 +-
 17 files changed, 760 insertions(+), 132 deletions(-)
 create mode 100644 tests/test_echo_tcp_sendmsg_recvmsg.c


Changeset truncated at 500 lines:

diff --git a/doc/socket_wrapper.1 b/doc/socket_wrapper.1
index 4e0dd01..c3cf835 100644
--- a/doc/socket_wrapper.1
+++ b/doc/socket_wrapper.1
@@ -2,12 +2,12 @@
 .\"     Title: socket_wrapper
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 2014-07-09
+.\"      Date: 2015-08-11
 .\"    Manual: \ \&
 .\"    Source: \ \&
 .\"  Language: English
 .\"
-.TH "SOCKET_WRAPPER" "1" "2014\-07\-09" "\ \&" "\ \&"
+.TH "SOCKET_WRAPPER" "1" "2015\-08\-11" "\ \&" "\ \&"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -85,6 +85,13 @@ Additionally, the default interface to be used by an application is defined with
 When debugging, it is often interesting to investigate the network traffic between the client and server within your application\&. If you define SOCKET_WRAPPER_PCAP_FILE=/path/to/file\&.pcap, socket_wrapper will dump all your network traffic to the specified file\&. After the test has been finished you\(cqre able to open the file for example with Wireshark\&.
 .RE
 .PP
+\fBSOCKET_WRAPPER_MTU\fR
+.RS 4
+With this variable you can change the MTU size\&. However we do not recomment to do that as the default size of 1500 byte is best for formatting PCAP files\&.
+.RE
+.sp
+The minimum value you can set is 512 and the maximum 32768\&.
+.PP
 \fBSOCKET_WRAPPER_DEBUGLEVEL\fR
 .RS 4
 If you need to see what is going on in socket_wrapper itself or try to find a bug, you can enable logging support in socket_wrapper if you built it with debug symbols\&.
diff --git a/doc/socket_wrapper.1.txt b/doc/socket_wrapper.1.txt
index 2ab330e..f4e82a8 100644
--- a/doc/socket_wrapper.1.txt
+++ b/doc/socket_wrapper.1.txt
@@ -1,6 +1,6 @@
 socket_wrapper(1)
 =================
-:revdate: 2014-07-09
+:revdate: 2015-08-11
 
 NAME
 ----
@@ -52,6 +52,13 @@ SOCKET_WRAPPER_PCAP_FILE=/path/to/file.pcap, socket_wrapper will dump all your
 network traffic to the specified file. After the test has been finished you're
 able to open the file for example with Wireshark.
 
+*SOCKET_WRAPPER_MTU*::
+
+With this variable you can change the MTU size. However we do not recomment to
+do that as the default size of 1500 byte is best for formatting PCAP files.
+
+The minimum value you can set is 512 and the maximum 32768.
+
 *SOCKET_WRAPPER_DEBUGLEVEL*::
 
 If you need to see what is going on in socket_wrapper itself or try to find a
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 1188c4e..01ab8d5 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -203,11 +203,12 @@ enum swrap_dbglvl_e {
 #define SOCKET_TYPE_CHAR_UDP_V6		'Y'
 
 /*
- * Cut down to 1500 byte packets for stream sockets,
- * which makes it easier to format PCAP capture files
- * (as the caller will simply continue from here)
+ * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
+ * format PCAP capture files (as the caller will simply continue from here).
  */
-#define SOCKET_MAX_PACKET 1500
+#define SOCKET_WRAPPER_MTU_DEFAULT 1500
+#define SOCKET_WRAPPER_MTU_MIN     512
+#define SOCKET_WRAPPER_MTU_MAX     32768
 
 #define SOCKET_MAX_SOCKETS 1024
 
@@ -912,6 +913,38 @@ static const char *socket_wrapper_dir(void)
 	return s;
 }
 
+static unsigned int socket_wrapper_mtu(void)
+{
+	static unsigned int max_mtu = 0;
+	unsigned int tmp;
+	const char *s;
+	char *endp;
+
+	if (max_mtu != 0) {
+		return max_mtu;
+	}
+
+	max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
+
+	s = getenv("SOCKET_WRAPPER_MTU");
+	if (s == NULL) {
+		goto done;
+	}
+
+	tmp = strtol(s, &endp, 10);
+	if (s == endp) {
+		goto done;
+	}
+
+	if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
+		goto done;
+	}
+	max_mtu = tmp;
+
+done:
+	return max_mtu;
+}
+
 bool socket_wrapper_enabled(void)
 {
 	const char *s = socket_wrapper_dir();
@@ -3743,7 +3776,9 @@ static ssize_t swrap_sendmsg_before(int fd,
 	}
 
 	switch (si->type) {
-	case SOCK_STREAM:
+	case SOCK_STREAM: {
+		unsigned long mtu;
+
 		if (!si->connected) {
 			errno = ENOTCONN;
 			return -1;
@@ -3753,22 +3788,23 @@ static ssize_t swrap_sendmsg_before(int fd,
 			break;
 		}
 
+		mtu = socket_wrapper_mtu();
 		for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
 			size_t nlen;
 			nlen = len + msg->msg_iov[i].iov_len;
-			if (nlen > SOCKET_MAX_PACKET) {
+			if (nlen > mtu) {
 				break;
 			}
 		}
 		msg->msg_iovlen = i;
 		if (msg->msg_iovlen == 0) {
 			*tmp_iov = msg->msg_iov[0];
-			tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
+			tmp_iov->iov_len = MIN(tmp_iov->iov_len, mtu);
 			msg->msg_iov = tmp_iov;
 			msg->msg_iovlen = 1;
 		}
 		break;
-
+	}
 	case SOCK_DGRAM:
 		if (si->connected) {
 			if (msg->msg_name) {
@@ -3958,7 +3994,8 @@ static int swrap_recvmsg_before(int fd,
 	(void)fd; /* unused */
 
 	switch (si->type) {
-	case SOCK_STREAM:
+	case SOCK_STREAM: {
+		unsigned int mtu;
 		if (!si->connected) {
 			errno = ENOTCONN;
 			return -1;
@@ -3968,22 +4005,23 @@ static int swrap_recvmsg_before(int fd,
 			break;
 		}
 
+		mtu = socket_wrapper_mtu();
 		for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
 			size_t nlen;
 			nlen = len + msg->msg_iov[i].iov_len;
-			if (nlen > SOCKET_MAX_PACKET) {
+			if (nlen > mtu) {
 				break;
 			}
 		}
 		msg->msg_iovlen = i;
 		if (msg->msg_iovlen == 0) {
 			*tmp_iov = msg->msg_iov[0];
-			tmp_iov->iov_len = MIN(tmp_iov->iov_len, SOCKET_MAX_PACKET);
+			tmp_iov->iov_len = MIN(tmp_iov->iov_len, mtu);
 			msg->msg_iov = tmp_iov;
 			msg->msg_iovlen = 1;
 		}
 		break;
-
+	}
 	case SOCK_DGRAM:
 		if (msg->msg_name == NULL) {
 			errno = EINVAL;
@@ -4051,6 +4089,19 @@ static int swrap_recvmsg_after(int fd,
 		avail += msg->msg_iov[i].iov_len;
 	}
 
+	/* Convert the socket address before we leave */
+	if (si->type == SOCK_DGRAM && un_addr != NULL) {
+		rc = sockaddr_convert_from_un(si,
+					      un_addr,
+					      un_addrlen,
+					      si->family,
+					      msg->msg_name,
+					      &msg->msg_namelen);
+		if (rc == -1) {
+			goto done;
+		}
+	}
+
 	if (avail == 0) {
 		rc = 0;
 		goto done;
@@ -4096,16 +4147,6 @@ static int swrap_recvmsg_after(int fd,
 		}
 
 		if (un_addr != NULL) {
-			rc = sockaddr_convert_from_un(si,
-						      un_addr,
-						      un_addrlen,
-						      si->family,
-						      msg->msg_name,
-						      &msg->msg_namelen);
-			if (rc == -1) {
-				goto done;
-			}
-
 			swrap_pcap_dump_packet(si,
 					  msg->msg_name,
 					  SWRAP_RECVFROM,
@@ -4549,9 +4590,6 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
 
 	ret = libc_recvmsg(s, &msg, flags);
 
-	msg.msg_name = omsg->msg_name;
-	msg.msg_namelen = omsg->msg_namelen;
-
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
 	msg_ctrllen_filled += msg.msg_controllen;
 	msg_ctrllen_left -= msg.msg_controllen;
@@ -4593,6 +4631,25 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
 #endif
 	omsg->msg_iovlen = msg.msg_iovlen;
 
+	/*
+	 * From the manpage:
+	 *
+	 * The  msg_name  field  points  to a caller-allocated buffer that is
+	 * used to return the source address if the socket is unconnected.  The
+	 * caller should set msg_namelen to the size of this buffer before this
+	 * call; upon return from a successful call, msg_name will contain the
+	 * length of the returned address.  If the application  does  not  need
+	 * to know the source address, msg_name can be specified as NULL.
+	 */
+	if (si->type == SOCK_STREAM) {
+		omsg->msg_namelen = 0;
+	} else if (omsg->msg_name != NULL &&
+	           omsg->msg_namelen != 0 &&
+	           omsg->msg_namelen >= msg.msg_namelen) {
+		memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
+		omsg->msg_namelen = msg.msg_namelen;
+	}
+
 	return ret;
 }
 
@@ -4627,8 +4684,11 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
 	tmp.iov_len = 0;
 
 	ZERO_STRUCT(msg);
-	msg.msg_name = omsg->msg_name;             /* optional address */
-	msg.msg_namelen = omsg->msg_namelen;       /* size of address */
+
+	if (si->connected == 0) {
+		msg.msg_name = omsg->msg_name;             /* optional address */
+		msg.msg_namelen = omsg->msg_namelen;       /* size of address */
+	}
 	msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
 	msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 84063a7..0cb7f78 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SWRAP_TESTS
     test_echo_tcp_connect
     test_echo_tcp_bind
     test_echo_tcp_socket_options
+    test_echo_tcp_sendmsg_recvmsg
     test_echo_tcp_write_read
     test_echo_tcp_writev_readv
     test_echo_tcp_get_peer_sock_name
diff --git a/tests/test_echo_tcp_bind.c b/tests/test_echo_tcp_bind.c
index b95724d..0baf0bd 100644
--- a/tests/test_echo_tcp_bind.c
+++ b/tests/test_echo_tcp_bind.c
@@ -19,19 +19,25 @@
 #include <rpc/rpc.h>
 #endif
 
-static void setup_echo_srv_tcp_ipv4(void **state)
+static int setup_echo_srv_tcp_ipv4(void **state)
 {
 	torture_setup_echo_srv_tcp_ipv4(state);
+
+	return 0;
 }
 
-static void setup_echo_srv_tcp_ipv6(void **state)
+static int setup_echo_srv_tcp_ipv6(void **state)
 {
 	torture_setup_echo_srv_tcp_ipv6(state);
+
+	return 0;
 }
 
-static void teardown(void **state)
+static int teardown(void **state)
 {
 	torture_teardown_echo_srv(state);
+
+	return 0;
 }
 
 static void test_bind_ipv4(void **state)
@@ -492,39 +498,39 @@ static void test_bindresvport_on_ipv6_sock_null(void **state)
 int main(void) {
 	int rc;
 
-	const UnitTest tests[] = {
-		unit_test_setup_teardown(test_bind_ipv4,
+	const struct CMUnitTest tcp_bind_tests[] = {
+		cmocka_unit_test_setup_teardown(test_bind_ipv4,
 					 setup_echo_srv_tcp_ipv4,
 					 teardown),
 #if 0 /* TODO */
-		unit_test_setup_teardown(test_bind_ipv4_addr_in_use,
+		cmocka_unit_test_setup_teardown(test_bind_ipv4_addr_in_use,
 					 setup_echo_srv_tcp_ipv4,
 					 teardown),
 #endif
 #ifdef HAVE_BINDRESVPORT
-		unit_test_setup_teardown(test_bindresvport_ipv4,
+		cmocka_unit_test_setup_teardown(test_bindresvport_ipv4,
 					 setup_echo_srv_tcp_ipv4,
 					 teardown),
-		unit_test_setup_teardown(test_bindresvport_ipv4_null,
+		cmocka_unit_test_setup_teardown(test_bindresvport_ipv4_null,
 					 setup_echo_srv_tcp_ipv4,
 					 teardown),
 #endif /* HAVE_BINDRESVPORT */
 #ifdef HAVE_IPV6
-		unit_test_setup_teardown(test_bind_on_ipv6_sock,
+		cmocka_unit_test_setup_teardown(test_bind_on_ipv6_sock,
 					 setup_echo_srv_tcp_ipv6,
 					 teardown),
 #ifdef HAVE_BINDRESVPORT
-		unit_test_setup_teardown(test_bindresvport_on_ipv6_sock,
+		cmocka_unit_test_setup_teardown(test_bindresvport_on_ipv6_sock,
 					 setup_echo_srv_tcp_ipv6,
 					 teardown),
-		unit_test_setup_teardown(test_bindresvport_on_ipv6_sock_null,
+		cmocka_unit_test_setup_teardown(test_bindresvport_on_ipv6_sock_null,
 					 setup_echo_srv_tcp_ipv6,
 					 teardown),
 #endif /* HAVE_BINDRESVPORT */
 #endif /* HAVE_IPV6 */
 	};
 
-	rc = run_tests(tests);
+	rc = cmocka_run_group_tests(tcp_bind_tests, NULL, NULL);
 
 	return rc;
 }
diff --git a/tests/test_echo_tcp_connect.c b/tests/test_echo_tcp_connect.c
index 0697e13..f97b5ac 100644
--- a/tests/test_echo_tcp_connect.c
+++ b/tests/test_echo_tcp_connect.c
@@ -15,14 +15,18 @@
 #include <stdio.h>
 #include <unistd.h>
 
-static void setup_echo_srv_tcp_ipv4(void **state)
+static int setup_echo_srv_tcp_ipv4(void **state)
 {
 	torture_setup_echo_srv_tcp_ipv4(state);
+
+	return 0;
 }
 
-static void teardown(void **state)
+static int teardown(void **state)
 {
 	torture_teardown_echo_srv(state);
+
+	return 0;
 }
 
 static void test_connect_broadcast_ipv4(void **state)
@@ -82,14 +86,16 @@ static void test_connect_downgrade_ipv6(void **state)
 int main(void) {
 	int rc;
 
-	const UnitTest tests[] = {
-		unit_test_setup_teardown(test_connect_broadcast_ipv4, setup_echo_srv_tcp_ipv4, teardown),
+	const struct CMUnitTest tcp_connect_tests[] = {
+		cmocka_unit_test(test_connect_broadcast_ipv4),
 #ifdef HAVE_IPV6
-		unit_test_setup_teardown(test_connect_downgrade_ipv6, setup_echo_srv_tcp_ipv4, teardown),
+		cmocka_unit_test(test_connect_downgrade_ipv6),
 #endif
 	};
 
-	rc = run_tests(tests);
+	rc = cmocka_run_group_tests(tcp_connect_tests,
+				    setup_echo_srv_tcp_ipv4,
+				    teardown);
 
 	return rc;
 }
diff --git a/tests/test_echo_tcp_get_peer_sock_name.c b/tests/test_echo_tcp_get_peer_sock_name.c
index 4be729c..9a00255 100644
--- a/tests/test_echo_tcp_get_peer_sock_name.c
+++ b/tests/test_echo_tcp_get_peer_sock_name.c
@@ -15,15 +15,19 @@
 #include <stdio.h>
 #include <unistd.h>
 
-static void setup_echo_srv_tcp_ipv4(void **state)
+static int setup_echo_srv_tcp_ipv4(void **state)
 {
 	torture_setup_echo_srv_tcp_ipv4(state);
 	setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "20", 1);
+
+	return 0;
 }
 
-static void teardown(void **state)
+static int teardown(void **state)
 {
 	torture_teardown_echo_srv(state);
+
+	return 0;
 }
 
 static void _assert_sockaddr_equal(struct torture_address *addr, const char *a,
@@ -446,25 +450,27 @@ static void test_connect_getsockname_getpeername_len(void **state)
 int main(void) {
 	int rc;
 
-	const UnitTest tests[] = {
-		unit_test_setup_teardown(test_connect_getsockname_getpeername,
-					 setup_echo_srv_tcp_ipv4,
-					 teardown),
-		unit_test_setup_teardown(test_connect_getsockname_getpeername_port,
-					 setup_echo_srv_tcp_ipv4,
-					 teardown),
-		unit_test_setup_teardown(test_connect_getsockname_getpeername_any,
-					 setup_echo_srv_tcp_ipv4,
-					 teardown),
-		unit_test_setup_teardown(test_connect_getsockname_getpeername_any_port,
-					 setup_echo_srv_tcp_ipv4,
-					 teardown),
-		unit_test_setup_teardown(test_connect_getsockname_getpeername_len,
-					 setup_echo_srv_tcp_ipv4,
-					 teardown),
+	const struct CMUnitTest sock_name_tests[] = {
+		cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername,
+						setup_echo_srv_tcp_ipv4,
+						teardown),
+		cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_port,
+						setup_echo_srv_tcp_ipv4,
+						teardown),
+		cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_any,
+						setup_echo_srv_tcp_ipv4,
+						teardown),
+		cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_any_port,
+						setup_echo_srv_tcp_ipv4,
+						teardown),
+		cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_len,
+						setup_echo_srv_tcp_ipv4,
+						teardown),
 	};
 
-	rc = run_tests(tests);
+	rc = cmocka_run_group_tests(sock_name_tests,
+				    NULL,
+				    NULL);
 
 	return rc;
 }
diff --git a/tests/test_echo_tcp_sendmsg_recvmsg.c b/tests/test_echo_tcp_sendmsg_recvmsg.c
new file mode 100644
index 0000000..2adaa75
--- /dev/null
+++ b/tests/test_echo_tcp_sendmsg_recvmsg.c
@@ -0,0 +1,273 @@
+#include <stdarg.h>
+#include <stddef.h>


-- 
Socket Wrapper Repository



More information about the samba-cvs mailing list