Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Sep 2013 13:51:19 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r255451 - head/tools/regression/sockets/sendfile
Message-ID:  <201309101351.r8ADpJuD041147@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Tue Sep 10 13:51:19 2013
New Revision: 255451
URL: http://svnweb.freebsd.org/changeset/base/255451

Log:
  Add a sendfile regression test for transmit length > file size.
  
  This test identified the issue fixed in FreeBSD-SA-13:11.sendfile.
  
  Sponsored by:	The FreeBSD Foundation
  Approved by:	re (glebius)

Modified:
  head/tools/regression/sockets/sendfile/sendfile.c

Modified: head/tools/regression/sockets/sendfile/sendfile.c
==============================================================================
--- head/tools/regression/sockets/sendfile/sendfile.c	Tue Sep 10 13:48:33 2013	(r255450)
+++ head/tools/regression/sockets/sendfile/sendfile.c	Tue Sep 10 13:51:19 2013	(r255451)
@@ -74,12 +74,13 @@ struct sendfile_test {
 	uint32_t	hdr_length;
 	uint32_t	offset;
 	uint32_t	length;
+	uint32_t	file_size;
 };
 
-int	file_fd;
-char	path[PATH_MAX];
-int	listen_socket;
-int	accept_socket;
+static int	file_fd;
+static char	path[PATH_MAX];
+static int	listen_socket;
+static int	accept_socket;
 
 static int test_th(struct test_header *th, uint32_t *header_length,
 		uint32_t *offset, uint32_t *length);
@@ -92,6 +93,7 @@ static int new_test_socket(int *connect_
 static void init_th(struct test_header *th, uint32_t header_length, 
 		uint32_t offset, uint32_t length);
 static int send_test(int connect_socket, struct sendfile_test);
+static int write_test_file(size_t file_size);
 static void run_parent(void);
 static void cleanup(void);
 
@@ -278,15 +280,12 @@ send_test(int connect_socket, struct sen
 	if (len != 0)
 		FAIL_ERR("lseek")
 
-	if (test.length == 0) {
-		struct stat st;
-		if (fstat(file_fd, &st) < 0)
-			FAIL_ERR("fstat")
-		length = st.st_size - test.offset;
-	}
-	else {
+	struct stat st;
+	if (fstat(file_fd, &st) < 0)
+		FAIL_ERR("fstat")
+	length = st.st_size - test.offset;
+	if (test.length > 0 && test.length < (uint32_t)length)
 		length = test.length;
-	}
 
 	init_th(&th, test.hdr_length, test.offset, length);
 
@@ -336,17 +335,55 @@ send_test(int connect_socket, struct sen
 	return (0);
 }
 
+static int
+write_test_file(size_t file_size)
+{
+	char *page_buffer;
+	ssize_t len;
+	static size_t current_file_size = 0;
+
+	if (file_size == current_file_size)
+		return (0);
+	else if (file_size < current_file_size) {
+		if (ftruncate(file_fd, file_size) != 0)
+			FAIL_ERR("ftruncate");
+		current_file_size = file_size;
+		return (0);
+	}
+
+	page_buffer = malloc(file_size);
+	if (page_buffer == NULL)
+		FAIL_ERR("malloc")
+	bzero(page_buffer, file_size);
+
+	len = write(file_fd, page_buffer, file_size);
+	if (len < 0)
+		FAIL_ERR("write")
+
+	len = lseek(file_fd, 0, SEEK_SET);
+	if (len < 0)
+		FAIL_ERR("lseek")
+	if (len != 0)
+		FAIL("len != 0")
+
+	free(page_buffer);
+	current_file_size = file_size;
+	return (0);
+}
+
 static void
 run_parent(void)
 {
 	int connect_socket;
 	int status;
 	int test_num;
+	int test_count;
 	int pid;
+	size_t desired_file_size = 0;
 
 	const int pagesize = getpagesize();
 
-	struct sendfile_test tests[10] = {
+	struct sendfile_test tests[] = {
  		{ .hdr_length = 0, .offset = 0, .length = 1 },
 		{ .hdr_length = 0, .offset = 0, .length = pagesize },
 		{ .hdr_length = 0, .offset = 1, .length = 1 },
@@ -356,12 +393,23 @@ run_parent(void)
 		{ .hdr_length = 0, .offset = 0, .length = 0 },
 		{ .hdr_length = 0, .offset = pagesize, .length = 0 },
 		{ .hdr_length = 0, .offset = 2*pagesize, .length = 0 },
-		{ .hdr_length = 0, .offset = TEST_PAGES*pagesize, .length = 0 }
+		{ .hdr_length = 0, .offset = TEST_PAGES*pagesize, .length = 0 },
+		{ .hdr_length = 0, .offset = 0, .length = pagesize,
+		    .file_size = 1 }
 	};
 
-	printf("1..10\n");
+	test_count = sizeof(tests) / sizeof(tests[0]);
+	printf("1..%d\n", test_count);
 
-	for (test_num = 1; test_num <= 10; test_num++) {
+	for (test_num = 1; test_num <= test_count; test_num++) {
+
+		desired_file_size = tests[test_num - 1].file_size;
+		if (desired_file_size == 0)
+			desired_file_size = TEST_PAGES * pagesize;
+		if (write_test_file(desired_file_size) != 0) {
+			printf("not ok %d\n", test_num);
+			continue;
+		}
 
 		pid = fork();
 		if (pid == -1) {
@@ -411,17 +459,11 @@ cleanup(void)
 int
 main(int argc, char *argv[])
 {
-	char *page_buffer;
 	int pagesize;
-	ssize_t len;
 
 	*path = '\0';
 
 	pagesize = getpagesize();
-	page_buffer = malloc(TEST_PAGES * pagesize);
-	if (page_buffer == NULL)
-		FAIL_ERR("malloc")
-	bzero(page_buffer, TEST_PAGES * pagesize);
 
 	if (argc == 1) {
 		snprintf(path, PATH_MAX, "/tmp/sendfile.XXXXXXXXXXXX");
@@ -439,16 +481,6 @@ main(int argc, char *argv[])
 
 	atexit(cleanup);
 
-	len = write(file_fd, page_buffer, TEST_PAGES * pagesize);
-	if (len < 0)
-		FAIL_ERR("write")
-
-	len = lseek(file_fd, 0, SEEK_SET);
-	if (len < 0)
-		FAIL_ERR("lseek")
-	if (len != 0)
-		FAIL("len != 0")
-
 	run_parent();
 	return (0);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309101351.r8ADpJuD041147>