All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02
@ 2019-07-29 10:11 Jinhui huang
  2019-07-29 10:11 ` [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03 Jinhui huang
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Jinhui huang @ 2019-07-29 10:11 UTC (permalink / raw)
  To: ltp

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 runtest/syscalls                                  |   2 -
 testcases/kernel/syscalls/ftruncate/.gitignore    |   2 -
 testcases/kernel/syscalls/ftruncate/ftruncate01.c | 235 ++++++------------
 testcases/kernel/syscalls/ftruncate/ftruncate02.c | 286 ----------------------
 4 files changed, 72 insertions(+), 453 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ftruncate/ftruncate02.c

diff --git a/runtest/syscalls b/runtest/syscalls
index d5a0ef8..9690a5b 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -354,8 +354,6 @@ fsync04 fsync04
 
 ftruncate01 ftruncate01
 ftruncate01_64 ftruncate01_64
-ftruncate02 ftruncate02
-ftruncate02_64 ftruncate02_64
 ftruncate03 ftruncate03
 ftruncate03_64 ftruncate03_64
 ftruncate04 ftruncate04
diff --git a/testcases/kernel/syscalls/ftruncate/.gitignore b/testcases/kernel/syscalls/ftruncate/.gitignore
index 814b707..b08763f 100644
--- a/testcases/kernel/syscalls/ftruncate/.gitignore
+++ b/testcases/kernel/syscalls/ftruncate/.gitignore
@@ -1,7 +1,5 @@
 /ftruncate01
 /ftruncate01_64
-/ftruncate02
-/ftruncate02_64
 /ftruncate03
 /ftruncate03_64
 /ftruncate04
diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate01.c b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
index 3309af5..c98b50b 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate01.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
@@ -1,203 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+ * Author: Wayne Boyer
  */
-
 /*
- * Test Name: ftruncate01
- *
  * Test Description:
- *  Verify that, ftruncate(2) succeeds to truncate a file to a specified
- *  length if the file indicated by file descriptor opened for writing.
- *
- * Expected Result:
- *  ftruncate(2) should return a value 0 and the length of the file after
- *  truncation should be equal to the length it is truncated to.
- *
- * Algorithm:
- *  Setup:
- *   Setup signal handling.
- *   Create temporary directory.
- *   Pause for SIGUSR1 if option specified.
- *
- *  Test:
- *   Loop if the proper options are given.
- *   Execute system call
- *   Check return code, if system call failed (return=-1)
- *	Log the errno and Issue a FAIL message.
- *   Otherwise,
- *	Verify the Functionality of system call
- *      if successful,
- *		Issue Functionality-Pass message.
- *      Otherwise,
- *		Issue Functionality-Fail message.
- *  Cleanup:
- *   Print errno log and/or timing stats if options given
- *   Delete the temporary directory created.
- *
- * Usage:  <for command-line>
- *  ftruncate01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- *  This test should be run by 'non-super-user' only.
- *
+ *  Verify that, ftruncate() succeeds to truncate a file to a certain length,
+ *  but it fails to attempt to read past the truncated length.
  */
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
-#include <signal.h>
-#include <inttypes.h>
 
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
 
-#define TESTFILE	"testfile"	/* file under test */
-#define FILE_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-#define BUF_SIZE	256	/* buffer size */
-#define FILE_SIZE	1024	/* test file size */
-#define TRUNC_LEN	256	/* truncation length */
+#define TESTFILE	"testfile"
 
-TCID_DEFINE(ftruncate01);
-int TST_TOTAL = 1;		/* Total number of test conditions */
-int fildes;			/* file descriptor for test file */
+#define TRUNC_LEN1	256
+#define TRUNC_LEN2	512
+#define FILE_SIZE	1024
 
-void setup();			/* setup function for the test */
-void cleanup();			/* cleanup function for the test */
+static int fd;
+static struct stat stat_buf;
 
-int main(int ac, char **av)
+static int get_file_length(off_t offset, char date)
 {
-	struct stat stat_buf;	/* stat(2) struct contents */
-	int lc;
-	off_t file_length;	/* test file length */
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
+	int i, read_len, file_length;
+	char buf[FILE_SIZE];
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
+	memset(buf, '*', sizeof(buf));
 
-		tst_count = 0;
+	SAFE_FSTAT(fd, &stat_buf);
+	file_length = stat_buf.st_size;
 
-		/*
-		 * Call ftruncate(2) to truncate a test file to a
-		 * specified length.
-		 */
-		TEST(ftruncate(fildes, TRUNC_LEN));
+	SAFE_LSEEK(fd, offset, SEEK_SET);
+	read_len = SAFE_READ(0, fd, buf, sizeof(buf));
 
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL | TTERRNO, "ftruncate(%s) failed",
-				 TESTFILE);
-			continue;
-		}
-		/*
-		 * Get the testfile information using
-		 * fstat(2).
-		 */
-		if (fstat(fildes, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup,
-				 "stat(2) of %s failed, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length = stat_buf.st_size;
-
-		/*
-		 * Check for expected size of testfile after
-		 * truncate(2) on it.
-		 */
-		if (file_length != TRUNC_LEN) {
-			tst_resm(TFAIL,
-				 "%s: Incorrect file size %" PRId64 ", "
-				 "Expected %d", TESTFILE,
-				 (int64_t) file_length, TRUNC_LEN);
-		} else {
-			tst_resm(TPASS, "Functionality of ftruncate() "
-				 "on %s successful", TESTFILE);
+	if (read_len > 0) {
+		for (i = 0; i < read_len; i++) {
+			if (buf[i] != date) {
+				tst_brk(TBROK,
+					"ftruncate() got incorrect date");
+			}
 		}
 	}
 
-	cleanup();
-	tst_exit();
+	return file_length;
 }
 
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- *  Create a temporary directory and change directory to it.
- *  Create a test file under temporary directory and write some
- *  data into it.
- */
-void setup(void)
+static void verify_ftruncate(void)
 {
-	int i;
-	int c, c_total = 0;	/* bytes to be written to file */
-	char tst_buff[BUF_SIZE];	/* buffer to hold data */
+	off_t file_length1, file_length2;
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
+	TEST(ftruncate(fd, TRUNC_LEN1));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "ftruncate() failed");
+		return;
+	}
 
-	tst_tmpdir();
+	file_length1 = get_file_length(0, 'a');
 
-	/* Fill the test buffer with the known data */
-	for (i = 0; i < BUF_SIZE; i++) {
-		tst_buff[i] = 'a';
-	}
+	TEST(ftruncate(fd, TRUNC_LEN2));
 
-	/* open a file for reading/writing */
-	fildes = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE);
+	file_length2 = get_file_length(TRUNC_LEN1, 0);
 
-	/* Write to the file 1k data from the buffer */
-	while (c_total < FILE_SIZE) {
-		if ((c = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
-			tst_brkm(TBROK | TERRNO, cleanup, "write(%s) failed",
-				 TESTFILE);
-		} else {
-			c_total += c;
+	/*
+	 * Check for expected size of testfile after issuing ftruncate() on it.
+	 * If the ftruncate() to a smaller file passed, then check to see if
+	 * file size was increased.
+	 * If the ftruncate()to a smaller file failed, then don't check.
+	 * Both results are allowed according to the SUS.
+	 */
+	if (TST_RET != -1) {
+		if (file_length1 != TRUNC_LEN1 || file_length2 != TRUNC_LEN2) {
+			tst_res(TFAIL, "ftruncate() got incorrected size");
+			return;
+		}
+	} else {
+		if (file_length1 != TRUNC_LEN1) {
+			tst_res(TFAIL, "ftruncate() got incorrected size");
+			return;
 		}
 	}
+
+	tst_res(TPASS, "ftruncate() secceeded");
 }
 
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- *	       completion or premature exit.
- *  Close the temporary file.
- *  Remove the test directory and testfile created in the setup.
- */
-void cleanup(void)
+static void setup(void)
 {
+	if (tst_fill_file(TESTFILE, 'a', FILE_SIZE, 1))
+		tst_brk(TBROK, "Failed to create test file");
 
-	/* Close the testfile after writing data into it */
-	if (close(fildes) == -1)
-		tst_brkm(TFAIL | TERRNO, NULL, "close(%s) failed", TESTFILE);
-
-	tst_rmdir();
+	fd = SAFE_OPEN(TESTFILE, O_RDWR);
+}
 
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
 }
+
+static struct tst_test test = {
+	.test_all = verify_ftruncate,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate02.c b/testcases/kernel/syscalls/ftruncate/ftruncate02.c
deleted file mode 100644
index 8ae226a..0000000
--- a/testcases/kernel/syscalls/ftruncate/ftruncate02.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Test Name: ftruncate02
- *
- * Test Description:
- *  Verify that, ftruncate(2) succeeds to truncate a file to a certain length,
- *  but the attempt to read past the truncated length will fail.
- *
- * Expected Result:
- *  ftruncate(2) should return a value 0 and the attempt to read past the
- *  truncated length will fail. In case where the file before  truncation was
- *  shorter, the bytes between the old and new should  be all zeroes.
- *
- * Algorithm:
- *  Setup:
- *   Setup signal handling.
- *   Create temporary directory.
- *   Pause for SIGUSR1 if option specified.
- *
- *  Test:
- *   Loop if the proper options are given.
- *   Execute system call
- *   Check return code, if system call failed (return=-1)
- *	Log the errno and Issue a FAIL message.
- *   Otherwise,
- *	Verify the Functionality of system call
- *      if successful,
- *		Issue Functionality-Pass message.
- *      Otherwise,
- *		Issue Functionality-Fail message.
- *  Cleanup:
- *   Print errno log and/or timing stats if options given
- *   Delete the temporary directory created.
- *
- * Usage:  <for command-line>
- *  ftruncate02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- *
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-#define TESTFILE	"testfile"	/* file under test */
-#define FILE_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-#define BUF_SIZE	256	/* buffer size */
-#define FILE_SIZE	1024	/* test file size */
-#define TRUNC_LEN1	256	/* truncation length */
-#define TRUNC_LEN2	512	/* truncation length */
-
-TCID_DEFINE(ftruncate02);
-int TST_TOTAL = 1;		/* Total number of test conditions */
-int fd;				/* file descriptor of testfile */
-char tst_buff[BUF_SIZE];	/* buffer to hold testfile contents */
-
-void setup();			/* setup function for the test */
-void cleanup();			/* cleanup function for the test */
-
-int main(int ac, char **av)
-{
-	struct stat stat_buf;	/* stat(2) struct contents */
-	int lc;
-	off_t file_length2;	/* test file length */
-	off_t file_length1;	/* test file length */
-	int rbytes, i;		/* bytes read from testfile */
-	int read_len;		/* total no. of bytes read from testfile */
-	int err_flag = 0;	/* error indicator flag */
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-		read_len = 0;
-
-		/*
-		 * Call ftruncate(2) to truncate a test file to a
-		 * specified length (TRUNC_LEN1).
-		 */
-		TEST(ftruncate(fd, TRUNC_LEN1));
-
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL | TTERRNO,
-				 "ftruncate(%s) to size %d failed", TESTFILE,
-				 TRUNC_LEN1);
-			continue;
-		}
-		/*
-		 * Get the testfile information using
-		 * fstat(2).
-		 */
-		if (fstat(fd, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
-				 " after 1st truncate, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length1 = stat_buf.st_size;
-
-		/*
-		 * Set the file pointer of testfile to the
-		 * beginning of the file.
-		 */
-		if (lseek(fd, 0, SEEK_SET) < 0) {
-			tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
-				 " after 1st ftruncate, error:%d",
-				 TESTFILE, errno);
-		}
-
-		/* Read the testfile from the beginning. */
-		while ((rbytes = read(fd, tst_buff,
-				      sizeof(tst_buff))) > 0) {
-			read_len += rbytes;
-		}
-
-		/*
-		 * Execute ftruncate(2) again to truncate
-		 * testfile to a size TRUNC_LEN2.
-		 */
-		TEST(ftruncate(fd, TRUNC_LEN2));
-
-		/*
-		 * Get the testfile information using
-		 * fstat(2)
-		 */
-		if (fstat(fd, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
-				 " after 2nd truncate, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length2 = stat_buf.st_size;
-
-		/*
-		 * Set the file pointer of testfile to the
-		 * offset TRUNC_LEN1 of testfile.
-		 */
-		if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) {
-			tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
-				 " after 2nd ftruncate, error:%d",
-				 TESTFILE, errno);
-		}
-
-		/* Read the testfile contents till EOF */
-		while ((rbytes = read(fd, tst_buff,
-				      sizeof(tst_buff))) > 0) {
-			for (i = 0; i < rbytes; i++) {
-				if (tst_buff[i] != 0) {
-					err_flag++;
-				}
-			}
-		}
-
-		/*
-		 * Check for expected size of testfile after
-		 * issuing ftruncate(2) on it. If the ftruncate(2)
-		 * to a smaller file passed, then check to see
-		 * if file size was increased. If the ftruncate(2)
-		 * to a smaller file failed, then don't check.
-		 * Both results are allowed according to the SUS.
-		 */
-
-		if (TEST_RETURN != -1) {
-			if ((file_length1 != TRUNC_LEN1) ||
-			    (file_length2 != TRUNC_LEN2) ||
-			    (read_len != TRUNC_LEN1) ||
-			    (err_flag != 0)) {
-				tst_resm(TFAIL,
-					 "Functionality of ftruncate(2) "
-					 "on %s Failed", TESTFILE);
-			} else {
-				tst_resm(TPASS,
-					 "Functionality of ftruncate(2) "
-					 "on %s successful", TESTFILE);
-			}
-		}
-		if (TEST_RETURN == -1) {
-			if ((file_length1 != TRUNC_LEN1) ||
-			    (read_len != TRUNC_LEN1) ||
-			    (err_flag != 0)) {
-				tst_resm(TFAIL,
-					 "Functionality of ftruncate(2) "
-					 "on %s Failed", TESTFILE);
-			} else {
-				tst_resm(TPASS,
-					 "Functionality of ftruncate(2) "
-					 "on %s successful", TESTFILE);
-			}
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- *  Create a temporary directory and change directory to it.
- *  Create a test file under temporary directory and write some
- *  data into it.
- */
-void setup(void)
-{
-	int i;
-	int wbytes;		/* bytes written to testfile */
-	int write_len = 0;	/* total no. of bytes written to testfile */
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	tst_tmpdir();
-
-	/* Fill the test buffer with the known data */
-	for (i = 0; i < BUF_SIZE; i++) {
-		tst_buff[i] = 'a';
-	}
-	/* open a file for reading/writing */
-	fd = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE);
-
-	/* Write to the file 1k data from the buffer */
-	while (write_len < FILE_SIZE) {
-		if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
-			tst_brkm(TBROK, cleanup, "write(%s) failed", TESTFILE);
-		} else {
-			write_len += wbytes;
-		}
-	}
-}
-
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- *	       completion or premature exit.
- *  Close the testfile.
- *  Remove the test directory and testfile created in the setup.
- */
-void cleanup(void)
-{
-
-	/* Close the testfile after writing data into it */
-	if (close(fd) == -1)
-		tst_brkm(TFAIL | TERRNO, NULL, "close(%s) failed", TESTFILE);
-
-	tst_rmdir();
-
-}
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03
  2019-07-29 10:11 [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
@ 2019-07-29 10:11 ` Jinhui huang
  2019-07-30 12:55   ` Cyril Hrubis
  2019-07-29 10:11 ` [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04 Jinhui huang
  2019-07-30 12:37 ` [LTP] [PATCH " Cyril Hrubis
  2 siblings, 1 reply; 12+ messages in thread
From: Jinhui huang @ 2019-07-29 10:11 UTC (permalink / raw)
  To: ltp

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/ftruncate/ftruncate03.c | 217 ++++++----------------
 1 file changed, 56 insertions(+), 161 deletions(-)

diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate03.c b/testcases/kernel/syscalls/ftruncate/ftruncate03.c
index bb4dd1e..9b4e13d 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate03.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate03.c
@@ -1,188 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Jay Huie
+ * Robbie Williamson
  */
-
 /*
- * Test Name: ftruncate03
- *
  * Test Description:
  *  Verify that,
- *  1) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
- *     socket is invalid.
- *  2) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
- *     file descriptor has an attempt to write, when open for read only.
- *  3) ftruncate(2) returns -1 and sets errno to EBADF if the file descriptor
- *     of the specified file is not valid.
- *
- * Expected Result:
- *  ftruncate() should fail with return value -1 and set expected errno.
- *
- * HISTORY
- *      02/2002 Written by Jay Huie
- *	02/2002 Adapted for and included into the LTP by Robbie Williamson
- *
- * RESTRICTIONS:
- *  This test should be run by 'non-super-user' only.
- *
+ *  1)ftruncate() fails with EINVAL if the file is a socket.
+ *  2)ftruncate() fails with EINVAL if the file descriptor opens with O_RDONLY.
+ *  3)ftruncate() fails with EBADF if the file descriptor is invalid.
  */
 
-#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#include <inttypes.h>
-#include <sys/types.h>
 #include <sys/socket.h>
-#include <fcntl.h>
-
-#include "test.h"
-
-#define TESTFILE	"ftruncate03_tst_file"
-
-TCID_DEFINE(ftruncate03);
-int TST_TOTAL = 3;
 
-int main(void)
-{
-	int wjh_ret = -1, wjh_f = -1, count = 0;
-	//used for the 2nd test
-	//make str > trunc_size characters long
-	char str[] = "THIS IS JAYS TEST FILE DATA";
-	int trunc_size = 4;
-	int flag = O_RDONLY;
-
-#ifdef DEBUG
-	printf("Starting test, possible errnos are; EBADF(%d) EINVAL(%d)\n",
-	       EBADF, EINVAL);
-	printf("\t\tENOENT(%d) EACCES(%d) EPERM(%d)\n\n", ENOENT, EACCES,
-	       EPERM);
-#endif
+#include "tst_test.h"
 
-	tst_tmpdir();
+#define TESTFILE "testfile"
 
-//TEST1: ftruncate on a socket is not valid, should fail w/ EINVAL
+static int sock_fd, read_fd, bad_fd = -1;
 
-#ifdef DEBUG
-	printf("Starting test1\n");
-#endif
-	wjh_f = socket(PF_INET, SOCK_STREAM, 0);
-	wjh_ret = ftruncate(wjh_f, 1);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if (wjh_ret == -1 && errno == EINVAL) {
-		tst_resm(TPASS, "Test Passed");
-	} else {
-		tst_resm(TFAIL,
-			 "ftruncate(socket)=%i (wanted -1), errno=%i (wanted EINVAL %i)",
-			 wjh_ret, errno, EINVAL);
-	}
-	close(wjh_f);
-	errno = 0;
-	wjh_ret = 0;
-	wjh_f = -1;
+static struct tcase {
+	int *fd;
+	int exp_errno;
+} tcases[] = {
+	{&sock_fd, EINVAL},
+	{&read_fd, EINVAL},
+	{&bad_fd, EBADF},
+};
 
-//TEST2: ftruncate on fd not open for writing should be EINVAL
+static void verify_ftruncate(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
 
-#ifdef DEBUG
-	printf("\nStarting test2\n");
-#endif
-	//create a file and fill it so we can truncate it in ReadOnly mode
-	//delete it first, ignore if it doesn't exist
-	unlink(TESTFILE);
-	errno = 0;
-	wjh_f = open(TESTFILE, O_RDWR | O_CREAT, 0644);
-	if (wjh_f == -1) {
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
-			 TESTFILE);
-	}
-	while (count < strlen(str)) {
-		if ((count += write(wjh_f, str, strlen(str))) == -1) {
-			tst_resm(TFAIL | TERRNO, "write() failed");
-			close(wjh_f);
-			tst_rmdir();
-			tst_exit();
-		}
+	TEST(ftruncate(*tc->fd, 4));
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "ftruncate() succeeded unexpectedly");
+		return;
 	}
-	close(wjh_f);
-	errno = 0;
 
-//Uncomment below if you want it to succeed, O_RDWR => success
-// flag = O_RDWR;
-#ifdef DEBUG
-	if (flag == O_RDWR) {
-		printf("\tLooks like it should succeed!\n");
+	if (TST_ERR == tc->exp_errno) {
+		tst_res(TPASS, "ftruncate() failed expectedly");
+	} else {
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() failed unexpectedly, got %s, expected",
+			tst_strerrno(tc->exp_errno));
 	}
-#endif
+}
 
-	wjh_f = open(TESTFILE, flag);
-	if (wjh_f == -1) {
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
-			 TESTFILE);
-	}
-	wjh_ret = ftruncate(wjh_f, trunc_size);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if ((flag == O_RDONLY) && (wjh_ret == -1) && (errno == EINVAL)) {
-		tst_resm(TPASS, "Test Passed");
-	} else if ((flag == O_RDWR)) {
-		if (wjh_ret == 0) {
-			tst_resm(TPASS, "Test Succeeded!");
-		} else {
-			tst_resm(TFAIL | TERRNO,
-				 "ftruncate(%s) should have succeeded, but didn't! ret="
-				 "%d (wanted 0)", TESTFILE, wjh_ret);
-		}
-	} else			//flag was O_RDONLY but return codes wrong
-	{
-		tst_resm(TFAIL,
-			 "ftruncate(rd_only_fd)=%i (wanted -1), errno=%i (wanted %i EINVAL)",
-			 wjh_ret, errno, EINVAL);
-	}
-	close(wjh_f);
-	errno = 0;
-	wjh_ret = 0;
-	wjh_f = -1;
+static void setup(void)
+{
+	sock_fd = SAFE_SOCKET(PF_INET, SOCK_STREAM, 0);
 
-//TEST3: invalid socket descriptor should fail w/ EBADF
+	if (tst_fill_file(TESTFILE, 'a', 100, 1))
+		tst_brk(TBROK, "Failed to create test file");
 
-#ifdef DEBUG
-	printf("\nStarting test3\n");
-#endif
-	wjh_f = -999999;	//should be a bad file descriptor
-	wjh_ret = ftruncate(wjh_f, trunc_size);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if (wjh_ret != -1 || errno != EBADF) {
-		tst_resm(TFAIL | TERRNO,
-			 "ftruncate(invalid_fd)=%d (wanted -1 and EBADF)",
-			 wjh_ret);
-	} else {
-		tst_resm(TPASS, "Test Passed");
-	}
+	read_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
+}
 
-	tst_rmdir();
+static void cleanup(void)
+{
+	if (sock_fd > 0)
+		SAFE_CLOSE(sock_fd);
 
-//Done Testing
-	tst_exit();
+	if (read_fd > 0)
+		SAFE_CLOSE(read_fd);
 }
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_ftruncate,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_tmpdir = 1,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04
  2019-07-29 10:11 [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  2019-07-29 10:11 ` [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03 Jinhui huang
@ 2019-07-29 10:11 ` Jinhui huang
  2019-07-30 13:06   ` Cyril Hrubis
  2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  2019-07-30 12:37 ` [LTP] [PATCH " Cyril Hrubis
  2 siblings, 2 replies; 12+ messages in thread
From: Jinhui huang @ 2019-07-29 10:11 UTC (permalink / raw)
  To: ltp

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/ftruncate/ftruncate04.c | 245 +++++++---------------
 1 file changed, 77 insertions(+), 168 deletions(-)

diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate04.c b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
index a1080be..679f70a 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate04.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
@@ -1,26 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+ /*
+  * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
+  * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+  *
+  * Robbie Williamson <robbiew@us.ibm.com>
+  * Roy Lee <roylee@andestech.com>
+  */
 /*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
+ * Test Description:
  *
- *  Robbie Williamson <robbiew@us.ibm.com>
- *  Roy Lee <roylee@andestech.com>
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
  * Tests truncate and mandatory record locking.
  *
  * Parent creates a file, child locks a region and sleeps.
@@ -31,111 +19,44 @@
  * Parent wakes up child, child exits, lock is unlocked.
  *
  * Parent checks that ftruncate now works in all cases.
+ *
  */
 
-#include <signal.h>
-#include <fcntl.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
-#include <sys/wait.h>
-#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
+#include <unistd.h>
+#include <stdlib.h>
 #include <sys/statvfs.h>
 
-#include "test.h"
-#include "safe_macros.h"
-
-#define RECLEN	100
-#define MOUNT_DIR "dir/"
-
-const char *TCID = "ftruncate04";
-int TST_TOTAL = 6;
-
-static int len = 8 * 1024;
-static char filename[80];
-
-static int recstart;
-static int reclen;
-
-static const char *device;
-static const char *fs_type;
-static int mount_flag;
-
-static void dochild(void);
-static void doparent(void);
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
-{
-	int lc, pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-#ifdef UCLINUX
-	maybe_run_child(&dochild, "sdd", filename, &recstart, &reclen);
-#endif
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		sprintf(filename, MOUNT_DIR"%s.%d.%d\n", TCID, getpid(), lc);
-
-		if (tst_fill_file(filename, 0, 1024, 8)) {
-			tst_brkm(TBROK, cleanup,
-			         "Failed to create test file '%s'", filename);
-		}
-
-		SAFE_CHMOD(cleanup, filename, 02666);
-
-		reclen = RECLEN;
-		/*
-		 * want at least RECLEN bytes BEFORE AND AFTER the
-		 * record lock.
-		 */
-		recstart = RECLEN + rand() % (len - 3 * RECLEN);
-
-		if ((pid = FORK_OR_VFORK()) < 0)
-			tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
-
-		if (pid == 0) {
-#ifdef UCLINUX
-			if (self_exec(av[0], "sdd", filename, recstart,
-			              reclen) < -1) {
-				tst_brkm(TBROK, cleanup, "self_exec() failed");
-			}
-#else
-			dochild();
-#endif
-		}
+#include "tst_test.h"
 
-		doparent();
-	}
+#define RECLEN  100
+#define MNTPOINT "mntpoint"
+#define TESTFILE MNTPOINT"/testfile"
 
-	cleanup();
-	tst_exit();
-}
+static int len = 1024;
+static int recstart, reclen;
 
 static void ftruncate_expect_fail(int fd, off_t offset, const char *msg)
 {
 	TEST(ftruncate(fd, offset));
 
-	if (TEST_RETURN == 0) {
-		tst_resm(TFAIL, "ftruncate() %s succeeded unexpectedly", msg);
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "ftruncate() %s succeeded unexpectedly", msg);
 		return;
 	}
 
-	if (TEST_ERRNO != EAGAIN) {
-		tst_resm(TFAIL | TTERRNO,
-		         "ftruncate() %s failed unexpectedly, expected EAGAIN",
-			 msg);
+	if (TST_ERR != EAGAIN) {
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() %s failed unexpectedly, expected EAGAIN",
+			msg);
 		return;
 	}
 
-	tst_resm(TPASS, "ftruncate() %s failed with EAGAIN", msg);
+	tst_res(TPASS, "ftruncate() %s failed with EAGAIN", msg);
 }
 
 static void ftruncate_expect_success(int fd, off_t offset, const char *msg)
@@ -144,46 +65,44 @@ static void ftruncate_expect_success(int fd, off_t offset, const char *msg)
 
 	TEST(ftruncate(fd, offset));
 
-	if (TEST_RETURN != 0) {
-		tst_resm(TFAIL | TTERRNO,
-		         "ftruncate() %s failed unexpectedly", msg);
+	if (TST_RET != 0) {
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() %s failed unexpectedly", msg);
 		return;
 	}
 
-	SAFE_FSTAT(cleanup, fd, &sb);
+	SAFE_FSTAT(fd, &sb);
 
 	if (sb.st_size != offset) {
-		tst_resm(TFAIL,
-			 "ftruncate() to %li bytes succeded but fstat() reports size %li",
-			 (long)offset, (long)sb.st_size);
+		tst_res(TFAIL,
+			"ftruncate() to %li bytes succeded but fstat() reports size %li",
+			(long)offset, (long)sb.st_size);
 		return;
 	}
 
-	tst_resm(TPASS, "ftruncate() %s succeded", msg);
+	tst_res(TPASS, "ftruncate() %s succeded", msg);
 }
 
 static void doparent(void)
 {
 	int fd;
 
-	/* Wait for child lock */
-	TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
+	TST_CHECKPOINT_WAIT(0);
 
-	fd = SAFE_OPEN(cleanup, filename, O_RDWR | O_NONBLOCK);
+	fd = SAFE_OPEN(TESTFILE, O_RDWR | O_NONBLOCK);
 
 	ftruncate_expect_fail(fd, RECLEN, "offset before lock");
 	ftruncate_expect_fail(fd, recstart + RECLEN/2, "offset in lock");
 	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");
 
-	/* wake child and wait for it to exit (to free record lock) */
-	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
-	SAFE_WAIT(NULL, NULL);
+	TST_CHECKPOINT_WAKE(0);
+	SAFE_WAIT(NULL);
 
 	ftruncate_expect_success(fd, recstart + RECLEN/2, "offset in lock");
 	ftruncate_expect_success(fd, recstart, "offset before lock");
 	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");
 
-	SAFE_CLOSE(NULL, fd);
+	SAFE_CLOSE(fd);
 }
 
 void dochild(void)
@@ -191,81 +110,71 @@ void dochild(void)
 	int fd;
 	struct flock flocks;
 
-#ifdef UCLINUX
-	TST_CHECKPOINT_INIT(NULL);
-#endif
-
-	fd = SAFE_OPEN(NULL, filename, O_RDWR);
+	fd = SAFE_OPEN(TESTFILE, O_RDWR);
 
-	tst_resm(TINFO, "Child locks file");
+	tst_res(TINFO, "Child locks file");
 
 	flocks.l_type = F_WRLCK;
 	flocks.l_whence = SEEK_CUR;
 	flocks.l_start = recstart;
 	flocks.l_len = reclen;
 
-	if (fcntl(fd, F_SETLKW, &flocks) < 0)
-		tst_brkm(TFAIL, NULL, "child fcntl failed");
+	SAFE_FCNTL(fd, F_SETLKW, &flocks);
 
-	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(NULL, 0);
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
 
-	tst_resm(TINFO, "Child unlocks file");
+	tst_res(TINFO, "Child unlocks file");
 
-	tst_exit();
+	exit(0);
 }
 
-static void setup(void)
+static void verify_ftruncate(void)
 {
-	struct statvfs fs;
-
-	srand(getpid());
-
-	tst_tmpdir();
+	int pid;
 
-	SAFE_MKDIR(tst_rmdir, MOUNT_DIR, 0777);
+	if (tst_fill_file(TESTFILE, 0, 1024, 8))
+		tst_brk(TBROK, "Failed to create test file");
 
-	TST_CHECKPOINT_INIT(tst_rmdir);
+	SAFE_CHMOD(TESTFILE, 02666);
 
-	if (statvfs(".", &fs) == -1)
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "statvfs failed");
+	reclen = RECLEN;
+	recstart = RECLEN + rand() % (len - 3 * RECLEN);
 
-	if ((fs.f_flag & MS_MANDLOCK))
-		return;
+	pid = SAFE_FORK();
 
-	tst_resm(TINFO, "TMPDIR does not support mandatory locks");
+	if (pid == 0)
+		dochild();
 
-	fs_type = tst_dev_fs_type();
-	device = tst_acquire_device(cleanup);
+	doparent();
+}
 
-	if (!device)
-		tst_brkm(TCONF, cleanup, "Failed to obtain block device");
+static void setup(void)
+{
+	struct statvfs fs;
 
-	/* the kernel returns EPERM when CONFIG_MANDATORY_FILE_LOCKING is not
-	 * supported - to avoid false negatives, mount the fs first without
-	 * flags and then remount it as MS_MANDLOCK */
+	if (statvfs(".", &fs) == -1)
+		tst_brk(TFAIL | TERRNO, "statvfs failed");
 
-	tst_mkfs(cleanup, device, fs_type, NULL, NULL);
-	SAFE_MOUNT(cleanup, device, MOUNT_DIR, fs_type, 0, NULL);
-	mount_flag = 1;
+	if ((fs.f_flag & MS_MANDLOCK))
+		return;
 
-	if (mount(NULL, MOUNT_DIR, NULL, MS_REMOUNT|MS_MANDLOCK, NULL) == -1) {
+	if (mount(NULL, MNTPOINT, NULL, MS_REMOUNT|MS_MANDLOCK, NULL) == -1) {
 		if (errno == EPERM) {
-			tst_brkm(TCONF, cleanup, "Mandatory locking (likely) "
-				 "not supported by this system");
+			tst_brk(TCONF,
+				"Mandatory lock not supported by this system");
 		} else {
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "Remount with MS_MANDLOCK failed");
+			tst_brk(TBROK | TTERRNO,
+				"Remount with MS_MANDLOCK failed");
 		}
 	}
 }
 
-static void cleanup(void)
-{
-	if (mount_flag && tst_umount(MOUNT_DIR))
-		tst_resm(TWARN | TERRNO, "umount(%s) failed", device);
-
-	if (device)
-		tst_release_device(device);
-
-	tst_rmdir();
-}
+static struct tst_test test = {
+	.test_all = verify_ftruncate,
+	.setup = setup,
+	.needs_checkpoints = 1,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02
  2019-07-29 10:11 [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  2019-07-29 10:11 ` [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03 Jinhui huang
  2019-07-29 10:11 ` [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04 Jinhui huang
@ 2019-07-30 12:37 ` Cyril Hrubis
  2 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-07-30 12:37 UTC (permalink / raw)
  To: ltp

Hi!
> diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate01.c b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
> index 3309af5..c98b50b 100644
> --- a/testcases/kernel/syscalls/ftruncate/ftruncate01.c
> +++ b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
> @@ -1,203 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0
                                       ^
				       -or-later

You have to replace the exact version of the licence.

>  /*
> - *
> - *   Copyright (c) International Business Machines  Corp., 2001
> - *
> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.

You are missing the IBM copyright here.

> + * Author: Wayne Boyer
>   */
> -
>  /*
> - * Test Name: ftruncate01
> - *
>   * Test Description:
> - *  Verify that, ftruncate(2) succeeds to truncate a file to a specified
> - *  length if the file indicated by file descriptor opened for writing.
> - *
> - * Expected Result:
> - *  ftruncate(2) should return a value 0 and the length of the file after
> - *  truncation should be equal to the length it is truncated to.
> - *
> - * Algorithm:
> - *  Setup:
> - *   Setup signal handling.
> - *   Create temporary directory.
> - *   Pause for SIGUSR1 if option specified.
> - *
> - *  Test:
> - *   Loop if the proper options are given.
> - *   Execute system call
> - *   Check return code, if system call failed (return=-1)
> - *	Log the errno and Issue a FAIL message.
> - *   Otherwise,
> - *	Verify the Functionality of system call
> - *      if successful,
> - *		Issue Functionality-Pass message.
> - *      Otherwise,
> - *		Issue Functionality-Fail message.
> - *  Cleanup:
> - *   Print errno log and/or timing stats if options given
> - *   Delete the temporary directory created.
> - *
> - * Usage:  <for command-line>
> - *  ftruncate01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -f   : Turn off functionality Testing.
> - *	       -i n : Execute test n times.
> - *	       -I x : Execute test for x seconds.
> - *	       -P x : Pause for x seconds between iterations.
> - *	       -t   : Turn on syscall timing.
> - *
> - * HISTORY
> - *	07/2001 Ported by Wayne Boyer
> - *
> - * RESTRICTIONS:
> - *  This test should be run by 'non-super-user' only.
> - *
> + *  Verify that, ftruncate() succeeds to truncate a file to a certain length,
> + *  but it fails to attempt to read past the truncated length.
          ^
	  What fails? The ftruncate does not read anything.

Also this should say that we are testing both the cases so that
resulting size is larger and smaller.

>   */
>  
>  #include <sys/types.h>
>  #include <sys/stat.h>
> +#include <unistd.h>
>  #include <fcntl.h>
>  #include <errno.h>
>  #include <string.h>
> -#include <signal.h>
> -#include <inttypes.h>
>  
> -#include "test.h"
> -#include "safe_macros.h"
> +#include "tst_test.h"
>  
> -#define TESTFILE	"testfile"	/* file under test */
> -#define FILE_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
> -#define BUF_SIZE	256	/* buffer size */
> -#define FILE_SIZE	1024	/* test file size */
> -#define TRUNC_LEN	256	/* truncation length */
> +#define TESTFILE	"testfile"
>  
> -TCID_DEFINE(ftruncate01);
> -int TST_TOTAL = 1;		/* Total number of test conditions */
> -int fildes;			/* file descriptor for test file */
> +#define TRUNC_LEN1	256
> +#define TRUNC_LEN2	512
> +#define FILE_SIZE	1024
>  
> -void setup();			/* setup function for the test */
> -void cleanup();			/* cleanup function for the test */
> +static int fd;
> +static struct stat stat_buf;
>  
> -int main(int ac, char **av)
> +static int get_file_length(off_t offset, char date)
                                                  ^
               ^				  data
               |
	       this name is misleading we are checking the
	       content of the file in this function as well

Why don't we just pass the expected file size to this function as well
and do all the checks in this function?

>  {
> -	struct stat stat_buf;	/* stat(2) struct contents */
> -	int lc;
> -	off_t file_length;	/* test file length */
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();
> +	int i, read_len, file_length;
> +	char buf[FILE_SIZE];
>  
> -	for (lc = 0; TEST_LOOPING(lc); lc++) {
> +	memset(buf, '*', sizeof(buf));
>  
> -		tst_count = 0;
> +	SAFE_FSTAT(fd, &stat_buf);
> +	file_length = stat_buf.st_size;
>  
> -		/*
> -		 * Call ftruncate(2) to truncate a test file to a
> -		 * specified length.
> -		 */
> -		TEST(ftruncate(fildes, TRUNC_LEN));
> +	SAFE_LSEEK(fd, offset, SEEK_SET);
> +	read_len = SAFE_READ(0, fd, buf, sizeof(buf));
>  
> -		if (TEST_RETURN == -1) {
> -			tst_resm(TFAIL | TTERRNO, "ftruncate(%s) failed",
> -				 TESTFILE);
> -			continue;
> -		}
> -		/*
> -		 * Get the testfile information using
> -		 * fstat(2).
> -		 */
> -		if (fstat(fildes, &stat_buf) < 0) {
> -			tst_brkm(TFAIL, cleanup,
> -				 "stat(2) of %s failed, error:%d",
> -				 TESTFILE, errno);
> -		}
> -		stat_buf.st_mode &= ~S_IFREG;
> -		file_length = stat_buf.st_size;
> -
> -		/*
> -		 * Check for expected size of testfile after
> -		 * truncate(2) on it.
> -		 */
> -		if (file_length != TRUNC_LEN) {
> -			tst_resm(TFAIL,
> -				 "%s: Incorrect file size %" PRId64 ", "
> -				 "Expected %d", TESTFILE,
> -				 (int64_t) file_length, TRUNC_LEN);
> -		} else {
> -			tst_resm(TPASS, "Functionality of ftruncate() "
> -				 "on %s successful", TESTFILE);
> +	if (read_len > 0) {
            ^
	    this is useless

If read_len <= 0 the loop will do zero iterations.

> +		for (i = 0; i < read_len; i++) {
> +			if (buf[i] != date) {
> +				tst_brk(TBROK,
> +					"ftruncate() got incorrect date");
                                                                     ^
								    data
> +			}
>  		}
>  	}
>  
> -	cleanup();
> -	tst_exit();
> +	return file_length;
>  }
>  
> -/*
> - * void
> - * setup() - performs all ONE TIME setup for this test.
> - *  Create a temporary directory and change directory to it.
> - *  Create a test file under temporary directory and write some
> - *  data into it.
> - */
> -void setup(void)
> +static void verify_ftruncate(void)
>  {
> -	int i;
> -	int c, c_total = 0;	/* bytes to be written to file */
> -	char tst_buff[BUF_SIZE];	/* buffer to hold data */
> +	off_t file_length1, file_length2;
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> -
> -	TEST_PAUSE;
> +	TEST(ftruncate(fd, TRUNC_LEN1));
> +	if (TST_RET == -1) {
> +		tst_res(TFAIL | TTERRNO, "ftruncate() failed");
> +		return;
> +	}
>  
> -	tst_tmpdir();
> +	file_length1 = get_file_length(0, 'a');
>  
> -	/* Fill the test buffer with the known data */
> -	for (i = 0; i < BUF_SIZE; i++) {
> -		tst_buff[i] = 'a';
> -	}
> +	TEST(ftruncate(fd, TRUNC_LEN2));
>  
> -	/* open a file for reading/writing */
> -	fildes = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE);
> +	file_length2 = get_file_length(TRUNC_LEN1, 0);
>  
> -	/* Write to the file 1k data from the buffer */
> -	while (c_total < FILE_SIZE) {
> -		if ((c = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
> -			tst_brkm(TBROK | TERRNO, cleanup, "write(%s) failed",
> -				 TESTFILE);
> -		} else {
> -			c_total += c;
> +	/*
> +	 * Check for expected size of testfile after issuing ftruncate() on it.
> +	 * If the ftruncate() to a smaller file passed, then check to see if
> +	 * file size was increased.
> +	 * If the ftruncate()to a smaller file failed, then don't check.
> +	 * Both results are allowed according to the SUS.
> +	 */

This is no longer true, the latest POSIX specification requires that the
size is increased.

See the bottom of CHANGE HISTORY in:

http://pubs.opengroup.org/onlinepubs/9699919799/

> +	if (TST_RET != -1) {
> +		if (file_length1 != TRUNC_LEN1 || file_length2 != TRUNC_LEN2) {
> +			tst_res(TFAIL, "ftruncate() got incorrected size");
> +			return;
> +		}
> +	} else {
> +		if (file_length1 != TRUNC_LEN1) {
> +			tst_res(TFAIL, "ftruncate() got incorrected size");
> +			return;
>  		}
>  	}
> +
> +	tst_res(TPASS, "ftruncate() secceeded");
                                      ^
				     succeeded
>  }
>  

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03
  2019-07-29 10:11 ` [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03 Jinhui huang
@ 2019-07-30 12:55   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-07-30 12:55 UTC (permalink / raw)
  To: ltp

Hi!
> --- a/testcases/kernel/syscalls/ftruncate/ftruncate03.c
> +++ b/testcases/kernel/syscalls/ftruncate/ftruncate03.c
> @@ -1,188 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0

Here as well -or-later

> + * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
>   *
> - *   Copyright (c) International Business Machines  Corp., 2002

Here as well, the IBM copyright should stay here.

> - *   This program is free software;  you can redistribute it and/or modify
> - *   it under the terms of the GNU General Public License as published by
> - *   the Free Software Foundation; either version 2 of the License, or
> - *   (at your option) any later version.
> - *
> - *   This program is distributed in the hope that it will be useful,
> - *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
> - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> - *   the GNU General Public License for more details.
> - *
> - *   You should have received a copy of the GNU General Public License
> - *   along with this program;  if not, write to the Free Software
> - *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + * Jay Huie
> + * Robbie Williamson
>   */
> -
>  /*
> - * Test Name: ftruncate03
> - *
>   * Test Description:
>   *  Verify that,
> - *  1) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
> - *     socket is invalid.
> - *  2) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
> - *     file descriptor has an attempt to write, when open for read only.
> - *  3) ftruncate(2) returns -1 and sets errno to EBADF if the file descriptor
> - *     of the specified file is not valid.
> - *
> - * Expected Result:
> - *  ftruncate() should fail with return value -1 and set expected errno.
> - *
> - * HISTORY
> - *      02/2002 Written by Jay Huie
> - *	02/2002 Adapted for and included into the LTP by Robbie Williamson
> - *
> - * RESTRICTIONS:
> - *  This test should be run by 'non-super-user' only.
> - *
> + *  1)ftruncate() fails with EINVAL if the file is a socket.
> + *  2)ftruncate() fails with EINVAL if the file descriptor opens with O_RDONLY.
> + *  3)ftruncate() fails with EBADF if the file descriptor is invalid.

We are still missing EINVAL when off_t is negative.

>   */
>  
> -#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
>  #include <unistd.h>
>  #include <errno.h>
>  #include <string.h>
> -#include <inttypes.h>
> -#include <sys/types.h>
>  #include <sys/socket.h>
> -#include <fcntl.h>
> -
> -#include "test.h"
> -
> -#define TESTFILE	"ftruncate03_tst_file"
> -
> -TCID_DEFINE(ftruncate03);
> -int TST_TOTAL = 3;
>  
> -int main(void)
> -{
> -	int wjh_ret = -1, wjh_f = -1, count = 0;
> -	//used for the 2nd test
> -	//make str > trunc_size characters long
> -	char str[] = "THIS IS JAYS TEST FILE DATA";
> -	int trunc_size = 4;
> -	int flag = O_RDONLY;
> -
> -#ifdef DEBUG
> -	printf("Starting test, possible errnos are; EBADF(%d) EINVAL(%d)\n",
> -	       EBADF, EINVAL);
> -	printf("\t\tENOENT(%d) EACCES(%d) EPERM(%d)\n\n", ENOENT, EACCES,
> -	       EPERM);
> -#endif
> +#include "tst_test.h"
>  
> -	tst_tmpdir();
> +#define TESTFILE "testfile"
>  
> -//TEST1: ftruncate on a socket is not valid, should fail w/ EINVAL
> +static int sock_fd, read_fd, bad_fd = -1;
>  
> -#ifdef DEBUG
> -	printf("Starting test1\n");
> -#endif
> -	wjh_f = socket(PF_INET, SOCK_STREAM, 0);
> -	wjh_ret = ftruncate(wjh_f, 1);
> -#ifdef DEBUG
> -	printf("DEBUG: fd: %d ret: %d errno(%d) %s\n",
> -	       wjh_f, wjh_ret, errno, strerror(errno));
> -#endif
> -	if (wjh_ret == -1 && errno == EINVAL) {
> -		tst_resm(TPASS, "Test Passed");
> -	} else {
> -		tst_resm(TFAIL,
> -			 "ftruncate(socket)=%i (wanted -1), errno=%i (wanted EINVAL %i)",
> -			 wjh_ret, errno, EINVAL);
> -	}
> -	close(wjh_f);
> -	errno = 0;
> -	wjh_ret = 0;
> -	wjh_f = -1;
> +static struct tcase {
> +	int *fd;
> +	int exp_errno;
> +} tcases[] = {
> +	{&sock_fd, EINVAL},
> +	{&read_fd, EINVAL},
> +	{&bad_fd, EBADF},
> +};
>  
> -//TEST2: ftruncate on fd not open for writing should be EINVAL
> +static void verify_ftruncate(unsigned int n)
> +{
> +	struct tcase *tc = &tcases[n];
>  
> -#ifdef DEBUG
> -	printf("\nStarting test2\n");
> -#endif
> -	//create a file and fill it so we can truncate it in ReadOnly mode
> -	//delete it first, ignore if it doesn't exist
> -	unlink(TESTFILE);
> -	errno = 0;
> -	wjh_f = open(TESTFILE, O_RDWR | O_CREAT, 0644);
> -	if (wjh_f == -1) {
> -		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
> -			 TESTFILE);
> -	}
> -	while (count < strlen(str)) {
> -		if ((count += write(wjh_f, str, strlen(str))) == -1) {
> -			tst_resm(TFAIL | TERRNO, "write() failed");
> -			close(wjh_f);
> -			tst_rmdir();
> -			tst_exit();
> -		}
> +	TEST(ftruncate(*tc->fd, 4));
> +	if (TST_RET != -1) {
> +		tst_res(TFAIL, "ftruncate() succeeded unexpectedly");

Here as well, we should print the TST_RET value.

> +		return;
>  	}
> -	close(wjh_f);
> -	errno = 0;
>  
> -//Uncomment below if you want it to succeed, O_RDWR => success
> -// flag = O_RDWR;
> -#ifdef DEBUG
> -	if (flag == O_RDWR) {
> -		printf("\tLooks like it should succeed!\n");
> +	if (TST_ERR == tc->exp_errno) {
> +		tst_res(TPASS, "ftruncate() failed expectedly");
                          ^
			  Can we please pass the TTERRNO here as well?
> +	} else {
> +		tst_res(TFAIL | TTERRNO,
> +			"ftruncate() failed unexpectedly, got %s, expected",
> +			tst_strerrno(tc->exp_errno));
>  	}
> -#endif
> +}
>  
> -	wjh_f = open(TESTFILE, flag);
> -	if (wjh_f == -1) {
> -		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
> -			 TESTFILE);
> -	}
> -	wjh_ret = ftruncate(wjh_f, trunc_size);
> -#ifdef DEBUG
> -	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
> -	       wjh_f, wjh_ret, errno, strerror(errno));
> -#endif
> -	if ((flag == O_RDONLY) && (wjh_ret == -1) && (errno == EINVAL)) {
> -		tst_resm(TPASS, "Test Passed");
> -	} else if ((flag == O_RDWR)) {
> -		if (wjh_ret == 0) {
> -			tst_resm(TPASS, "Test Succeeded!");
> -		} else {
> -			tst_resm(TFAIL | TERRNO,
> -				 "ftruncate(%s) should have succeeded, but didn't! ret="
> -				 "%d (wanted 0)", TESTFILE, wjh_ret);
> -		}
> -	} else			//flag was O_RDONLY but return codes wrong
> -	{
> -		tst_resm(TFAIL,
> -			 "ftruncate(rd_only_fd)=%i (wanted -1), errno=%i (wanted %i EINVAL)",
> -			 wjh_ret, errno, EINVAL);
> -	}
> -	close(wjh_f);
> -	errno = 0;
> -	wjh_ret = 0;
> -	wjh_f = -1;
> +static void setup(void)
> +{
> +	sock_fd = SAFE_SOCKET(PF_INET, SOCK_STREAM, 0);
>  
> -//TEST3: invalid socket descriptor should fail w/ EBADF
> +	if (tst_fill_file(TESTFILE, 'a', 100, 1))
> +		tst_brk(TBROK, "Failed to create test file");

There is no need to fill the file, we can just pass O_CREAT to the open
below.

> -#ifdef DEBUG
> -	printf("\nStarting test3\n");
> -#endif
> -	wjh_f = -999999;	//should be a bad file descriptor
> -	wjh_ret = ftruncate(wjh_f, trunc_size);
> -#ifdef DEBUG
> -	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
> -	       wjh_f, wjh_ret, errno, strerror(errno));
> -#endif
> -	if (wjh_ret != -1 || errno != EBADF) {
> -		tst_resm(TFAIL | TERRNO,
> -			 "ftruncate(invalid_fd)=%d (wanted -1 and EBADF)",
> -			 wjh_ret);
> -	} else {
> -		tst_resm(TPASS, "Test Passed");
> -	}
> +	read_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
> +}
>  
> -	tst_rmdir();
> +static void cleanup(void)
> +{
> +	if (sock_fd > 0)
> +		SAFE_CLOSE(sock_fd);
>  
> -//Done Testing
> -	tst_exit();
> +	if (read_fd > 0)
> +		SAFE_CLOSE(read_fd);
>  }
> +
> +static struct tst_test test = {
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.test = verify_ftruncate,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.needs_tmpdir = 1,
> +};
> -- 
> 1.8.3.1
> 
> 
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04
  2019-07-29 10:11 ` [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04 Jinhui huang
@ 2019-07-30 13:06   ` Cyril Hrubis
  2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  1 sibling, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-07-30 13:06 UTC (permalink / raw)
  To: ltp

Hi!
> +// SPDX-License-Identifier: GPL-2.0

Here as well -or-later

> + /*
> +  * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
> +  * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.

Here as well, missing IBM copyright.

> +  * Robbie Williamson <robbiew@us.ibm.com>
> +  * Roy Lee <roylee@andestech.com>
> +  */


-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02
  2019-07-29 10:11 ` [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04 Jinhui huang
  2019-07-30 13:06   ` Cyril Hrubis
@ 2019-08-01  7:42   ` Jinhui huang
  2019-08-01  7:42     ` [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test Jinhui huang
                       ` (2 more replies)
  1 sibling, 3 replies; 12+ messages in thread
From: Jinhui huang @ 2019-08-01  7:42 UTC (permalink / raw)
  To: ltp

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 runtest/syscalls                                  |   2 -
 testcases/kernel/syscalls/ftruncate/.gitignore    |   2 -
 testcases/kernel/syscalls/ftruncate/ftruncate01.c | 237 +++++-------------
 testcases/kernel/syscalls/ftruncate/ftruncate02.c | 286 ----------------------
 4 files changed, 66 insertions(+), 461 deletions(-)
 delete mode 100644 testcases/kernel/syscalls/ftruncate/ftruncate02.c

diff --git a/runtest/syscalls b/runtest/syscalls
index a68a4c9..bf5a5f6 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -354,8 +354,6 @@ fsync04 fsync04
 
 ftruncate01 ftruncate01
 ftruncate01_64 ftruncate01_64
-ftruncate02 ftruncate02
-ftruncate02_64 ftruncate02_64
 ftruncate03 ftruncate03
 ftruncate03_64 ftruncate03_64
 ftruncate04 ftruncate04
diff --git a/testcases/kernel/syscalls/ftruncate/.gitignore b/testcases/kernel/syscalls/ftruncate/.gitignore
index 814b707..b08763f 100644
--- a/testcases/kernel/syscalls/ftruncate/.gitignore
+++ b/testcases/kernel/syscalls/ftruncate/.gitignore
@@ -1,7 +1,5 @@
 /ftruncate01
 /ftruncate01_64
-/ftruncate02
-/ftruncate02_64
 /ftruncate03
 /ftruncate03_64
 /ftruncate04
diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate01.c b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
index 3309af5..930d86c 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate01.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate01.c
@@ -1,203 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines  Corp., 2001
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+ * Author: Wayne Boyer
  */
-
 /*
- * Test Name: ftruncate01
- *
  * Test Description:
- *  Verify that, ftruncate(2) succeeds to truncate a file to a specified
- *  length if the file indicated by file descriptor opened for writing.
- *
- * Expected Result:
- *  ftruncate(2) should return a value 0 and the length of the file after
- *  truncation should be equal to the length it is truncated to.
- *
- * Algorithm:
- *  Setup:
- *   Setup signal handling.
- *   Create temporary directory.
- *   Pause for SIGUSR1 if option specified.
- *
- *  Test:
- *   Loop if the proper options are given.
- *   Execute system call
- *   Check return code, if system call failed (return=-1)
- *	Log the errno and Issue a FAIL message.
- *   Otherwise,
- *	Verify the Functionality of system call
- *      if successful,
- *		Issue Functionality-Pass message.
- *      Otherwise,
- *		Issue Functionality-Fail message.
- *  Cleanup:
- *   Print errno log and/or timing stats if options given
- *   Delete the temporary directory created.
- *
- * Usage:  <for command-line>
- *  ftruncate01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- *  This test should be run by 'non-super-user' only.
- *
+ *  Verify that, ftruncate() succeeds to truncate a file to a certain length,
+ *  if the file previously is smaller than the truncated size, ftruncate()
+ *  shall increase the size of the file.
  */
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
-#include <signal.h>
-#include <inttypes.h>
 
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
 
-#define TESTFILE	"testfile"	/* file under test */
-#define FILE_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-#define BUF_SIZE	256	/* buffer size */
-#define FILE_SIZE	1024	/* test file size */
-#define TRUNC_LEN	256	/* truncation length */
+#define TESTFILE	"testfile"
 
-TCID_DEFINE(ftruncate01);
-int TST_TOTAL = 1;		/* Total number of test conditions */
-int fildes;			/* file descriptor for test file */
+#define TRUNC_LEN1	256
+#define TRUNC_LEN2	512
+#define FILE_SIZE	1024
 
-void setup();			/* setup function for the test */
-void cleanup();			/* cleanup function for the test */
+static int fd;
 
-int main(int ac, char **av)
+static void check_and_report(off_t offset, char data, off_t trunc_len)
 {
-	struct stat stat_buf;	/* stat(2) struct contents */
-	int lc;
-	off_t file_length;	/* test file length */
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-
-		/*
-		 * Call ftruncate(2) to truncate a test file to a
-		 * specified length.
-		 */
-		TEST(ftruncate(fildes, TRUNC_LEN));
-
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL | TTERRNO, "ftruncate(%s) failed",
-				 TESTFILE);
-			continue;
-		}
-		/*
-		 * Get the testfile information using
-		 * fstat(2).
-		 */
-		if (fstat(fildes, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup,
-				 "stat(2) of %s failed, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length = stat_buf.st_size;
-
-		/*
-		 * Check for expected size of testfile after
-		 * truncate(2) on it.
-		 */
-		if (file_length != TRUNC_LEN) {
-			tst_resm(TFAIL,
-				 "%s: Incorrect file size %" PRId64 ", "
-				 "Expected %d", TESTFILE,
-				 (int64_t) file_length, TRUNC_LEN);
-		} else {
-			tst_resm(TPASS, "Functionality of ftruncate() "
-				 "on %s successful", TESTFILE);
-		}
-	}
+	int i, file_length;
+	char buf[FILE_SIZE];
+	struct stat stat_buf;
 
-	cleanup();
-	tst_exit();
-}
+	memset(buf, '*', sizeof(buf));
 
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- *  Create a temporary directory and change directory to it.
- *  Create a test file under temporary directory and write some
- *  data into it.
- */
-void setup(void)
-{
-	int i;
-	int c, c_total = 0;	/* bytes to be written to file */
-	char tst_buff[BUF_SIZE];	/* buffer to hold data */
+	SAFE_FSTAT(fd, &stat_buf);
+	file_length = stat_buf.st_size;
 
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+	if (file_length != trunc_len) {
+		tst_brk(TBROK, "ftruncate() got incorrected size: %d",
+			file_length);
+	}
 
-	TEST_PAUSE;
+	SAFE_LSEEK(fd, offset, SEEK_SET);
+	SAFE_READ(0, fd, buf, sizeof(buf));
 
-	tst_tmpdir();
+	for (i = 0; i < TRUNC_LEN1; i++) {
+		if (buf[i] != data)
+			tst_brk(TBROK, "ftruncate() got incorrect data");
+	}
+
+	tst_res(TPASS, "ftruncate() succeeded");
+}
 
-	/* Fill the test buffer with the known data */
-	for (i = 0; i < BUF_SIZE; i++) {
-		tst_buff[i] = 'a';
+static void verify_ftruncate(void)
+{
+	tst_res(TINFO, "Truncated length smaller than file size");
+	TEST(ftruncate(fd, TRUNC_LEN1));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "ftruncate() failed");
+		return;
 	}
 
-	/* open a file for reading/writing */
-	fildes = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE);
-
-	/* Write to the file 1k data from the buffer */
-	while (c_total < FILE_SIZE) {
-		if ((c = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) {
-			tst_brkm(TBROK | TERRNO, cleanup, "write(%s) failed",
-				 TESTFILE);
-		} else {
-			c_total += c;
-		}
+	check_and_report(0, 'a', TRUNC_LEN1);
+
+	tst_res(TINFO, "Truncated length exceeds file size");
+	TEST(ftruncate(fd, TRUNC_LEN2));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "ftruncate() failed");
+		return;
 	}
+
+	check_and_report(TRUNC_LEN1, 0, TRUNC_LEN2);
 }
 
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- *	       completion or premature exit.
- *  Close the temporary file.
- *  Remove the test directory and testfile created in the setup.
- */
-void cleanup(void)
+static void setup(void)
 {
+	if (tst_fill_file(TESTFILE, 'a', FILE_SIZE, 1))
+		tst_brk(TBROK, "Failed to create test file");
 
-	/* Close the testfile after writing data into it */
-	if (close(fildes) == -1)
-		tst_brkm(TFAIL | TERRNO, NULL, "close(%s) failed", TESTFILE);
-
-	tst_rmdir();
+	fd = SAFE_OPEN(TESTFILE, O_RDWR);
+}
 
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
 }
+
+static struct tst_test test = {
+	.test_all = verify_ftruncate,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate02.c b/testcases/kernel/syscalls/ftruncate/ftruncate02.c
deleted file mode 100644
index 8ae226a..0000000
--- a/testcases/kernel/syscalls/ftruncate/ftruncate02.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- *
- *   Copyright (c) International Business Machines  Corp., 2001
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Test Name: ftruncate02
- *
- * Test Description:
- *  Verify that, ftruncate(2) succeeds to truncate a file to a certain length,
- *  but the attempt to read past the truncated length will fail.
- *
- * Expected Result:
- *  ftruncate(2) should return a value 0 and the attempt to read past the
- *  truncated length will fail. In case where the file before  truncation was
- *  shorter, the bytes between the old and new should  be all zeroes.
- *
- * Algorithm:
- *  Setup:
- *   Setup signal handling.
- *   Create temporary directory.
- *   Pause for SIGUSR1 if option specified.
- *
- *  Test:
- *   Loop if the proper options are given.
- *   Execute system call
- *   Check return code, if system call failed (return=-1)
- *	Log the errno and Issue a FAIL message.
- *   Otherwise,
- *	Verify the Functionality of system call
- *      if successful,
- *		Issue Functionality-Pass message.
- *      Otherwise,
- *		Issue Functionality-Fail message.
- *  Cleanup:
- *   Print errno log and/or timing stats if options given
- *   Delete the temporary directory created.
- *
- * Usage:  <for command-line>
- *  ftruncate02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- *     where,  -c n : Run n copies concurrently.
- *             -f   : Turn off functionality Testing.
- *	       -i n : Execute test n times.
- *	       -I x : Execute test for x seconds.
- *	       -P x : Pause for x seconds between iterations.
- *	       -t   : Turn on syscall timing.
- *
- * HISTORY
- *	07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS:
- *
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-#define TESTFILE	"testfile"	/* file under test */
-#define FILE_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-#define BUF_SIZE	256	/* buffer size */
-#define FILE_SIZE	1024	/* test file size */
-#define TRUNC_LEN1	256	/* truncation length */
-#define TRUNC_LEN2	512	/* truncation length */
-
-TCID_DEFINE(ftruncate02);
-int TST_TOTAL = 1;		/* Total number of test conditions */
-int fd;				/* file descriptor of testfile */
-char tst_buff[BUF_SIZE];	/* buffer to hold testfile contents */
-
-void setup();			/* setup function for the test */
-void cleanup();			/* cleanup function for the test */
-
-int main(int ac, char **av)
-{
-	struct stat stat_buf;	/* stat(2) struct contents */
-	int lc;
-	off_t file_length2;	/* test file length */
-	off_t file_length1;	/* test file length */
-	int rbytes, i;		/* bytes read from testfile */
-	int read_len;		/* total no. of bytes read from testfile */
-	int err_flag = 0;	/* error indicator flag */
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		tst_count = 0;
-		read_len = 0;
-
-		/*
-		 * Call ftruncate(2) to truncate a test file to a
-		 * specified length (TRUNC_LEN1).
-		 */
-		TEST(ftruncate(fd, TRUNC_LEN1));
-
-		if (TEST_RETURN == -1) {
-			tst_resm(TFAIL | TTERRNO,
-				 "ftruncate(%s) to size %d failed", TESTFILE,
-				 TRUNC_LEN1);
-			continue;
-		}
-		/*
-		 * Get the testfile information using
-		 * fstat(2).
-		 */
-		if (fstat(fd, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
-				 " after 1st truncate, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length1 = stat_buf.st_size;
-
-		/*
-		 * Set the file pointer of testfile to the
-		 * beginning of the file.
-		 */
-		if (lseek(fd, 0, SEEK_SET) < 0) {
-			tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
-				 " after 1st ftruncate, error:%d",
-				 TESTFILE, errno);
-		}
-
-		/* Read the testfile from the beginning. */
-		while ((rbytes = read(fd, tst_buff,
-				      sizeof(tst_buff))) > 0) {
-			read_len += rbytes;
-		}
-
-		/*
-		 * Execute ftruncate(2) again to truncate
-		 * testfile to a size TRUNC_LEN2.
-		 */
-		TEST(ftruncate(fd, TRUNC_LEN2));
-
-		/*
-		 * Get the testfile information using
-		 * fstat(2)
-		 */
-		if (fstat(fd, &stat_buf) < 0) {
-			tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed"
-				 " after 2nd truncate, error:%d",
-				 TESTFILE, errno);
-		}
-		stat_buf.st_mode &= ~S_IFREG;
-		file_length2 = stat_buf.st_size;
-
-		/*
-		 * Set the file pointer of testfile to the
-		 * offset TRUNC_LEN1 of testfile.
-		 */
-		if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) {
-			tst_brkm(TFAIL, cleanup, "lseek(2) on %s failed"
-				 " after 2nd ftruncate, error:%d",
-				 TESTFILE, errno);
-		}
-
-		/* Read the testfile contents till EOF */
-		while ((rbytes = read(fd, tst_buff,
-				      sizeof(tst_buff))) > 0) {
-			for (i = 0; i < rbytes; i++) {
-				if (tst_buff[i] != 0) {
-					err_flag++;
-				}
-			}
-		}
-
-		/*
-		 * Check for expected size of testfile after
-		 * issuing ftruncate(2) on it. If the ftruncate(2)
-		 * to a smaller file passed, then check to see
-		 * if file size was increased. If the ftruncate(2)
-		 * to a smaller file failed, then don't check.
-		 * Both results are allowed according to the SUS.
-		 */
-
-		if (TEST_RETURN != -1) {
-			if ((file_length1 != TRUNC_LEN1) ||
-			    (file_length2 != TRUNC_LEN2) ||
-			    (read_len != TRUNC_LEN1) ||
-			    (err_flag != 0)) {
-				tst_resm(TFAIL,
-					 "Functionality of ftruncate(2) "
-					 "on %s Failed", TESTFILE);
-			} else {
-				tst_resm(TPASS,
-					 "Functionality of ftruncate(2) "
-					 "on %s successful", TESTFILE);
-			}
-		}
-		if (TEST_RETURN == -1) {
-			if ((file_length1 != TRUNC_LEN1) ||
-			    (read_len != TRUNC_LEN1) ||
-			    (err_flag != 0)) {
-				tst_resm(TFAIL,
-					 "Functionality of ftruncate(2) "
-					 "on %s Failed", TESTFILE);
-			} else {
-				tst_resm(TPASS,
-					 "Functionality of ftruncate(2) "
-					 "on %s successful", TESTFILE);
-			}
-		}
-	}
-
-	cleanup();
-	tst_exit();
-}
-
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- *  Create a temporary directory and change directory to it.
- *  Create a test file under temporary directory and write some
- *  data into it.
- */
-void setup(void)
-{
-	int i;
-	int wbytes;		/* bytes written to testfile */
-	int write_len = 0;	/* total no. of bytes written to testfile */
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	tst_tmpdir();
-
-	/* Fill the test buffer with the known data */
-	for (i = 0; i < BUF_SIZE; i++) {
-		tst_buff[i] = 'a';
-	}
-	/* open a file for reading/writing */
-	fd = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE);
-
-	/* Write to the file 1k data from the buffer */
-	while (write_len < FILE_SIZE) {
-		if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) {
-			tst_brkm(TBROK, cleanup, "write(%s) failed", TESTFILE);
-		} else {
-			write_len += wbytes;
-		}
-	}
-}
-
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- *	       completion or premature exit.
- *  Close the testfile.
- *  Remove the test directory and testfile created in the setup.
- */
-void cleanup(void)
-{
-
-	/* Close the testfile after writing data into it */
-	if (close(fd) == -1)
-		tst_brkm(TFAIL | TERRNO, NULL, "close(%s) failed", TESTFILE);
-
-	tst_rmdir();
-
-}
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test
  2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
@ 2019-08-01  7:42     ` Jinhui huang
  2019-08-13 14:37       ` Cyril Hrubis
  2019-08-01  7:42     ` [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04 Jinhui huang
  2019-08-13 14:20     ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Cyril Hrubis
  2 siblings, 1 reply; 12+ messages in thread
From: Jinhui huang @ 2019-08-01  7:42 UTC (permalink / raw)
  To: ltp

1) Cleanup and convert to new API.
2) Add EINVAL error test for ftruncate().

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/ftruncate/ftruncate03.c | 235 +++++++---------------
 1 file changed, 71 insertions(+), 164 deletions(-)

diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate03.c b/testcases/kernel/syscalls/ftruncate/ftruncate03.c
index bb4dd1e..b83e0c2 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate03.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate03.c
@@ -1,188 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
+ * Copyright (c) International Business Machines  Corp., 2002
+ * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
  *
- *   Copyright (c) International Business Machines  Corp., 2002
- *
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Jay Huie
+ * Robbie Williamson
  */
-
 /*
- * Test Name: ftruncate03
- *
  * Test Description:
  *  Verify that,
- *  1) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
- *     socket is invalid.
- *  2) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
- *     file descriptor has an attempt to write, when open for read only.
- *  3) ftruncate(2) returns -1 and sets errno to EBADF if the file descriptor
- *     of the specified file is not valid.
- *
- * Expected Result:
- *  ftruncate() should fail with return value -1 and set expected errno.
- *
- * HISTORY
- *      02/2002 Written by Jay Huie
- *	02/2002 Adapted for and included into the LTP by Robbie Williamson
- *
- * RESTRICTIONS:
- *  This test should be run by 'non-super-user' only.
- *
+ *  1)ftruncate() fails with EINVAL if the file is a socket.
+ *  2)ftruncate() fails with EINVAL if the file descriptor opens with O_RDONLY.
+ *  3)ftruncate() fails with EINVAL if the length is negative.
+ *  4)ftruncate() fails with EBADF if the file descriptor is invalid.
  */
 
-#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#include <inttypes.h>
-#include <sys/types.h>
 #include <sys/socket.h>
-#include <fcntl.h>
 
-#include "test.h"
+#include "tst_test.h"
+
+#define TESTFILE1	"testfile1"
+#define TESTFILE2	"testfile2"
 
-#define TESTFILE	"ftruncate03_tst_file"
+static int sock_fd, read_fd, fd;
+static int bad_fd = -1;
 
-TCID_DEFINE(ftruncate03);
-int TST_TOTAL = 3;
+static struct tcase {
+	int *fd;
+	off_t length;
+	int exp_errno;
+} tcases[] = {
+	{&sock_fd, 4, EINVAL},
+	{&read_fd, 4, EINVAL},
+	{&fd, -1, EINVAL},
+	{&bad_fd, 4, EBADF},
+};
 
-int main(void)
+static void verify_ftruncate(unsigned int n)
 {
-	int wjh_ret = -1, wjh_f = -1, count = 0;
-	//used for the 2nd test
-	//make str > trunc_size characters long
-	char str[] = "THIS IS JAYS TEST FILE DATA";
-	int trunc_size = 4;
-	int flag = O_RDONLY;
-
-#ifdef DEBUG
-	printf("Starting test, possible errnos are; EBADF(%d) EINVAL(%d)\n",
-	       EBADF, EINVAL);
-	printf("\t\tENOENT(%d) EACCES(%d) EPERM(%d)\n\n", ENOENT, EACCES,
-	       EPERM);
-#endif
-
-	tst_tmpdir();
-
-//TEST1: ftruncate on a socket is not valid, should fail w/ EINVAL
-
-#ifdef DEBUG
-	printf("Starting test1\n");
-#endif
-	wjh_f = socket(PF_INET, SOCK_STREAM, 0);
-	wjh_ret = ftruncate(wjh_f, 1);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if (wjh_ret == -1 && errno == EINVAL) {
-		tst_resm(TPASS, "Test Passed");
-	} else {
-		tst_resm(TFAIL,
-			 "ftruncate(socket)=%i (wanted -1), errno=%i (wanted EINVAL %i)",
-			 wjh_ret, errno, EINVAL);
-	}
-	close(wjh_f);
-	errno = 0;
-	wjh_ret = 0;
-	wjh_f = -1;
-
-//TEST2: ftruncate on fd not open for writing should be EINVAL
-
-#ifdef DEBUG
-	printf("\nStarting test2\n");
-#endif
-	//create a file and fill it so we can truncate it in ReadOnly mode
-	//delete it first, ignore if it doesn't exist
-	unlink(TESTFILE);
-	errno = 0;
-	wjh_f = open(TESTFILE, O_RDWR | O_CREAT, 0644);
-	if (wjh_f == -1) {
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
-			 TESTFILE);
-	}
-	while (count < strlen(str)) {
-		if ((count += write(wjh_f, str, strlen(str))) == -1) {
-			tst_resm(TFAIL | TERRNO, "write() failed");
-			close(wjh_f);
-			tst_rmdir();
-			tst_exit();
-		}
-	}
-	close(wjh_f);
-	errno = 0;
-
-//Uncomment below if you want it to succeed, O_RDWR => success
-// flag = O_RDWR;
-#ifdef DEBUG
-	if (flag == O_RDWR) {
-		printf("\tLooks like it should succeed!\n");
-	}
-#endif
+	struct tcase *tc = &tcases[n];
 
-	wjh_f = open(TESTFILE, flag);
-	if (wjh_f == -1) {
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
-			 TESTFILE);
-	}
-	wjh_ret = ftruncate(wjh_f, trunc_size);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if ((flag == O_RDONLY) && (wjh_ret == -1) && (errno == EINVAL)) {
-		tst_resm(TPASS, "Test Passed");
-	} else if ((flag == O_RDWR)) {
-		if (wjh_ret == 0) {
-			tst_resm(TPASS, "Test Succeeded!");
-		} else {
-			tst_resm(TFAIL | TERRNO,
-				 "ftruncate(%s) should have succeeded, but didn't! ret="
-				 "%d (wanted 0)", TESTFILE, wjh_ret);
-		}
-	} else			//flag was O_RDONLY but return codes wrong
-	{
-		tst_resm(TFAIL,
-			 "ftruncate(rd_only_fd)=%i (wanted -1), errno=%i (wanted %i EINVAL)",
-			 wjh_ret, errno, EINVAL);
+	TEST(ftruncate(*tc->fd, tc->length));
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "ftruncate() succeeded unexpectedly and got %ld",
+			TST_RET);
+		return;
 	}
-	close(wjh_f);
-	errno = 0;
-	wjh_ret = 0;
-	wjh_f = -1;
-
-//TEST3: invalid socket descriptor should fail w/ EBADF
-
-#ifdef DEBUG
-	printf("\nStarting test3\n");
-#endif
-	wjh_f = -999999;	//should be a bad file descriptor
-	wjh_ret = ftruncate(wjh_f, trunc_size);
-#ifdef DEBUG
-	printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
-	       wjh_f, wjh_ret, errno, strerror(errno));
-#endif
-	if (wjh_ret != -1 || errno != EBADF) {
-		tst_resm(TFAIL | TERRNO,
-			 "ftruncate(invalid_fd)=%d (wanted -1 and EBADF)",
-			 wjh_ret);
+
+	if (TST_ERR == tc->exp_errno) {
+		tst_res(TPASS | TTERRNO, "ftruncate() failed expectedly");
 	} else {
-		tst_resm(TPASS, "Test Passed");
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() failed unexpectedly, got %s, expected",
+			tst_strerrno(tc->exp_errno));
 	}
+}
+
+static void setup(void)
+{
+	sock_fd = SAFE_SOCKET(PF_INET, SOCK_STREAM, 0);
 
-	tst_rmdir();
+	read_fd = SAFE_OPEN(TESTFILE1, O_RDONLY | O_CREAT, 0644);
 
-//Done Testing
-	tst_exit();
+	if (tst_fill_file(TESTFILE2, 'a', 100, 1))
+		tst_brk(TBROK, "Failed to create test file");
+
+	fd = SAFE_OPEN(TESTFILE2, O_RDWR);
 }
+
+static void cleanup(void)
+{
+	if (sock_fd > 0)
+		SAFE_CLOSE(sock_fd);
+
+	if (read_fd > 0)
+		SAFE_CLOSE(read_fd);
+
+	if (fd > 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_ftruncate,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_tmpdir = 1,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04
  2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  2019-08-01  7:42     ` [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test Jinhui huang
@ 2019-08-01  7:42     ` Jinhui huang
  2019-08-13 15:10       ` Cyril Hrubis
  2019-08-13 14:20     ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Cyril Hrubis
  2 siblings, 1 reply; 12+ messages in thread
From: Jinhui huang @ 2019-08-01  7:42 UTC (permalink / raw)
  To: ltp

Signed-off-by: Jinhui huang <huangjh.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/ftruncate/ftruncate04.c | 244 +++++++---------------
 1 file changed, 77 insertions(+), 167 deletions(-)

diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate04.c b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
index a1080be..097c283 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate04.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
@@ -1,26 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+ /*
+  * Copyright (c) International Business Machines  Corp., 2002
+  * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
+  * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
+  *
+  * Robbie Williamson <robbiew@us.ibm.com>
+  * Roy Lee <roylee@andestech.com>
+  */
 /*
- * Copyright (c) International Business Machines  Corp., 2002
- * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
+ * Test Description:
  *
- *  Robbie Williamson <robbiew@us.ibm.com>
- *  Roy Lee <roylee@andestech.com>
- *
- * This program is free software;  you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY;  without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;  if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
  * Tests truncate and mandatory record locking.
  *
  * Parent creates a file, child locks a region and sleeps.
@@ -31,111 +20,44 @@
  * Parent wakes up child, child exits, lock is unlocked.
  *
  * Parent checks that ftruncate now works in all cases.
+ *
  */
 
-#include <signal.h>
-#include <fcntl.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
-#include <sys/wait.h>
-#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
+#include <unistd.h>
+#include <stdlib.h>
 #include <sys/statvfs.h>
 
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
 
 #define RECLEN	100
-#define MOUNT_DIR "dir/"
-
-const char *TCID = "ftruncate04";
-int TST_TOTAL = 6;
-
-static int len = 8 * 1024;
-static char filename[80];
-
-static int recstart;
-static int reclen;
-
-static const char *device;
-static const char *fs_type;
-static int mount_flag;
-
-static void dochild(void);
-static void doparent(void);
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
-{
-	int lc, pid;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
-
-#ifdef UCLINUX
-	maybe_run_child(&dochild, "sdd", filename, &recstart, &reclen);
-#endif
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		sprintf(filename, MOUNT_DIR"%s.%d.%d\n", TCID, getpid(), lc);
-
-		if (tst_fill_file(filename, 0, 1024, 8)) {
-			tst_brkm(TBROK, cleanup,
-			         "Failed to create test file '%s'", filename);
-		}
-
-		SAFE_CHMOD(cleanup, filename, 02666);
-
-		reclen = RECLEN;
-		/*
-		 * want at least RECLEN bytes BEFORE AND AFTER the
-		 * record lock.
-		 */
-		recstart = RECLEN + rand() % (len - 3 * RECLEN);
-
-		if ((pid = FORK_OR_VFORK()) < 0)
-			tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
-
-		if (pid == 0) {
-#ifdef UCLINUX
-			if (self_exec(av[0], "sdd", filename, recstart,
-			              reclen) < -1) {
-				tst_brkm(TBROK, cleanup, "self_exec() failed");
-			}
-#else
-			dochild();
-#endif
-		}
-
-		doparent();
-	}
+#define MNTPOINT	"mntpoint"
+#define TESTFILE	MNTPOINT"/testfile"
 
-	cleanup();
-	tst_exit();
-}
+static int len = 1024;
+static int recstart, reclen;
 
 static void ftruncate_expect_fail(int fd, off_t offset, const char *msg)
 {
 	TEST(ftruncate(fd, offset));
 
-	if (TEST_RETURN == 0) {
-		tst_resm(TFAIL, "ftruncate() %s succeeded unexpectedly", msg);
+	if (TST_RET == 0) {
+		tst_res(TFAIL, "ftruncate() %s succeeded unexpectedly", msg);
 		return;
 	}
 
-	if (TEST_ERRNO != EAGAIN) {
-		tst_resm(TFAIL | TTERRNO,
-		         "ftruncate() %s failed unexpectedly, expected EAGAIN",
-			 msg);
+	if (TST_ERR != EAGAIN) {
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() %s failed unexpectedly, expected EAGAIN",
+			msg);
 		return;
 	}
 
-	tst_resm(TPASS, "ftruncate() %s failed with EAGAIN", msg);
+	tst_res(TPASS, "ftruncate() %s failed with EAGAIN", msg);
 }
 
 static void ftruncate_expect_success(int fd, off_t offset, const char *msg)
@@ -144,46 +66,44 @@ static void ftruncate_expect_success(int fd, off_t offset, const char *msg)
 
 	TEST(ftruncate(fd, offset));
 
-	if (TEST_RETURN != 0) {
-		tst_resm(TFAIL | TTERRNO,
-		         "ftruncate() %s failed unexpectedly", msg);
+	if (TST_RET != 0) {
+		tst_res(TFAIL | TTERRNO,
+			"ftruncate() %s failed unexpectedly", msg);
 		return;
 	}
 
-	SAFE_FSTAT(cleanup, fd, &sb);
+	SAFE_FSTAT(fd, &sb);
 
 	if (sb.st_size != offset) {
-		tst_resm(TFAIL,
-			 "ftruncate() to %li bytes succeded but fstat() reports size %li",
-			 (long)offset, (long)sb.st_size);
+		tst_res(TFAIL,
+			"ftruncate() to %li bytes succeded but fstat() reports size %li",
+			(long)offset, (long)sb.st_size);
 		return;
 	}
 
-	tst_resm(TPASS, "ftruncate() %s succeded", msg);
+	tst_res(TPASS, "ftruncate() %s succeded", msg);
 }
 
 static void doparent(void)
 {
 	int fd;
 
-	/* Wait for child lock */
-	TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
+	TST_CHECKPOINT_WAIT(0);
 
-	fd = SAFE_OPEN(cleanup, filename, O_RDWR | O_NONBLOCK);
+	fd = SAFE_OPEN(TESTFILE, O_RDWR | O_NONBLOCK);
 
 	ftruncate_expect_fail(fd, RECLEN, "offset before lock");
 	ftruncate_expect_fail(fd, recstart + RECLEN/2, "offset in lock");
 	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");
 
-	/* wake child and wait for it to exit (to free record lock) */
-	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
-	SAFE_WAIT(NULL, NULL);
+	TST_CHECKPOINT_WAKE(0);
+	SAFE_WAIT(NULL);
 
 	ftruncate_expect_success(fd, recstart + RECLEN/2, "offset in lock");
 	ftruncate_expect_success(fd, recstart, "offset before lock");
 	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");
 
-	SAFE_CLOSE(NULL, fd);
+	SAFE_CLOSE(fd);
 }
 
 void dochild(void)
@@ -191,81 +111,71 @@ void dochild(void)
 	int fd;
 	struct flock flocks;
 
-#ifdef UCLINUX
-	TST_CHECKPOINT_INIT(NULL);
-#endif
-
-	fd = SAFE_OPEN(NULL, filename, O_RDWR);
+	fd = SAFE_OPEN(TESTFILE, O_RDWR);
 
-	tst_resm(TINFO, "Child locks file");
+	tst_res(TINFO, "Child locks file");
 
 	flocks.l_type = F_WRLCK;
 	flocks.l_whence = SEEK_CUR;
 	flocks.l_start = recstart;
 	flocks.l_len = reclen;
 
-	if (fcntl(fd, F_SETLKW, &flocks) < 0)
-		tst_brkm(TFAIL, NULL, "child fcntl failed");
+	SAFE_FCNTL(fd, F_SETLKW, &flocks);
 
-	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(NULL, 0);
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
 
-	tst_resm(TINFO, "Child unlocks file");
+	tst_res(TINFO, "Child unlocks file");
 
-	tst_exit();
+	exit(0);
 }
 
-static void setup(void)
+static void verify_ftruncate(void)
 {
-	struct statvfs fs;
-
-	srand(getpid());
-
-	tst_tmpdir();
+	int pid;
 
-	SAFE_MKDIR(tst_rmdir, MOUNT_DIR, 0777);
+	if (tst_fill_file(TESTFILE, 0, 1024, 8))
+		tst_brk(TBROK, "Failed to create test file");
 
-	TST_CHECKPOINT_INIT(tst_rmdir);
+	SAFE_CHMOD(TESTFILE, 02666);
 
-	if (statvfs(".", &fs) == -1)
-		tst_brkm(TFAIL | TERRNO, tst_rmdir, "statvfs failed");
+	reclen = RECLEN;
+	recstart = RECLEN + rand() % (len - 3 * RECLEN);
 
-	if ((fs.f_flag & MS_MANDLOCK))
-		return;
+	pid = SAFE_FORK();
 
-	tst_resm(TINFO, "TMPDIR does not support mandatory locks");
+	if (pid == 0)
+		dochild();
 
-	fs_type = tst_dev_fs_type();
-	device = tst_acquire_device(cleanup);
+	doparent();
+}
 
-	if (!device)
-		tst_brkm(TCONF, cleanup, "Failed to obtain block device");
+static void setup(void)
+{
+	struct statvfs fs;
 
-	/* the kernel returns EPERM when CONFIG_MANDATORY_FILE_LOCKING is not
-	 * supported - to avoid false negatives, mount the fs first without
-	 * flags and then remount it as MS_MANDLOCK */
+	if (statvfs(".", &fs) == -1)
+		tst_brk(TFAIL | TERRNO, "statvfs failed");
 
-	tst_mkfs(cleanup, device, fs_type, NULL, NULL);
-	SAFE_MOUNT(cleanup, device, MOUNT_DIR, fs_type, 0, NULL);
-	mount_flag = 1;
+	if ((fs.f_flag & MS_MANDLOCK))
+		return;
 
-	if (mount(NULL, MOUNT_DIR, NULL, MS_REMOUNT|MS_MANDLOCK, NULL) == -1) {
+	if (mount(NULL, MNTPOINT, NULL, MS_REMOUNT|MS_MANDLOCK, NULL) == -1) {
 		if (errno == EPERM) {
-			tst_brkm(TCONF, cleanup, "Mandatory locking (likely) "
-				 "not supported by this system");
+			tst_brk(TCONF,
+				"Mandatory lock not supported by this system");
 		} else {
-			tst_brkm(TBROK | TERRNO, cleanup,
-				 "Remount with MS_MANDLOCK failed");
+			tst_brk(TBROK | TTERRNO,
+				"Remount with MS_MANDLOCK failed");
 		}
 	}
 }
 
-static void cleanup(void)
-{
-	if (mount_flag && tst_umount(MOUNT_DIR))
-		tst_resm(TWARN | TERRNO, "umount(%s) failed", device);
-
-	if (device)
-		tst_release_device(device);
-
-	tst_rmdir();
-}
+static struct tst_test test = {
+	.test_all = verify_ftruncate,
+	.setup = setup,
+	.needs_checkpoints = 1,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+};
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02
  2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
  2019-08-01  7:42     ` [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test Jinhui huang
  2019-08-01  7:42     ` [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04 Jinhui huang
@ 2019-08-13 14:20     ` Cyril Hrubis
  2 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-08-13 14:20 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with a minor change, thanks.

> +	SAFE_FSTAT(fd, &stat_buf);
> +	file_length = stat_buf.st_size;
>  
> -	tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +	if (file_length != trunc_len) {
> +		tst_brk(TBROK, "ftruncate() got incorrected size: %d",
> +			file_length);

Changed this to tst_res(TFAIL, ...) followed by return, since this is by
no means TBROK.

> +	}
>  
> -	TEST_PAUSE;
> +	SAFE_LSEEK(fd, offset, SEEK_SET);
> +	SAFE_READ(0, fd, buf, sizeof(buf));
>  
> -	tst_tmpdir();
> +	for (i = 0; i < TRUNC_LEN1; i++) {
> +		if (buf[i] != data)
> +			tst_brk(TBROK, "ftruncate() got incorrect data");

And here as well.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test
  2019-08-01  7:42     ` [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test Jinhui huang
@ 2019-08-13 14:37       ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-08-13 14:37 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with a very minor change, thanks.

I've removed the tst_fill_file() since we don't have to have non-empty
file for the test and added O_CREAT and mode to the open in the test
setup.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04
  2019-08-01  7:42     ` [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04 Jinhui huang
@ 2019-08-13 15:10       ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2019-08-13 15:10 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with a few changes, thanks.

diff --git a/testcases/kernel/syscalls/ftruncate/ftruncate04.c b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
index 097c283f4..53d395d1f 100644
--- a/testcases/kernel/syscalls/ftruncate/ftruncate04.c
+++ b/testcases/kernel/syscalls/ftruncate/ftruncate04.c
@@ -38,7 +38,7 @@
 #define MNTPOINT	"mntpoint"
 #define TESTFILE	MNTPOINT"/testfile"
 
-static int len = 1024;
+static int len = 8 * 1024;
                  ^
		  This was needlessly modified so I just returned it to
		  previous value.

 static int recstart, reclen;
 
 static void ftruncate_expect_fail(int fd, off_t offset, const char *msg)
@@ -151,14 +151,11 @@ static void verify_ftruncate(void)
 
 static void setup(void)
 {
-	struct statvfs fs;
-
-	if (statvfs(".", &fs) == -1)
-		tst_brk(TFAIL | TERRNO, "statvfs failed");
-
-	if ((fs.f_flag & MS_MANDLOCK))
-		return;
-

When the test was mounting the device in the setup this code was here to
skip the mkfs and mount in a case that the tmp was mounted with
mandatory locking, but after the change to .mount_device it became
meaningless. Moreover it would break the test in a case that the TMPDIR
was in fact mounted with mandatory locking.

+	 /*
+	  * Kernel returns EPERM when CONFIG_MANDATORY_FILE_LOCKING is not
+	  * supported - to avoid false negatives, mount the fs first without
+	  * flags and then remount it as MS_MANDLOCK
+	  */

And I've restored this comment as this is one of the places where it
makes sense to explain why we are not mounting the fs with MS_MANDLOCK
in the first place.

 	if (mount(NULL, MNTPOINT, NULL, MS_REMOUNT|MS_MANDLOCK, NULL) == -1) {
 		if (errno == EPERM) {
 			tst_brk(TCONF,
@@ -177,5 +174,6 @@ static struct tst_test test = {
 	.needs_tmpdir = 1,
 	.forks_child = 1,
 	.mount_device = 1,
+	.needs_root = 1,
 	.mntpoint = MNTPOINT,
 };

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-08-13 15:10 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-29 10:11 [LTP] [PATCH 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
2019-07-29 10:11 ` [LTP] [PATCH 2/3] syscalls/ftruncate: Rewrite ftruncate03 Jinhui huang
2019-07-30 12:55   ` Cyril Hrubis
2019-07-29 10:11 ` [LTP] [PATCH 3/3] syscalls/ftruncate: Rewtite ftruncate04 Jinhui huang
2019-07-30 13:06   ` Cyril Hrubis
2019-08-01  7:42   ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Jinhui huang
2019-08-01  7:42     ` [LTP] [PATCH v2 2/3] syscalls/ftruncate: Rewrite ftruncate03 and add new error test Jinhui huang
2019-08-13 14:37       ` Cyril Hrubis
2019-08-01  7:42     ` [LTP] [PATCH v2 3/3] syscalls/ftruncate: Rewrite ftruncate04 Jinhui huang
2019-08-13 15:10       ` Cyril Hrubis
2019-08-13 14:20     ` [LTP] [PATCH v2 1/3] syscalls/ftruncate: Rewrite ftruncate01 and merge ftruncate02 Cyril Hrubis
2019-07-30 12:37 ` [LTP] [PATCH " Cyril Hrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.