All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dai Shili <daisl.fnst@fujitsu.com>
To: <ltp@lists.linux.it>
Subject: [LTP] [PATCH] syscalls/pwrite04: Convert to new API
Date: Fri, 12 Nov 2021 19:09:21 -0500	[thread overview]
Message-ID: <1636762161-26777-1-git-send-email-daisl.fnst@fujitsu.com> (raw)

1) use SAFE macro
2) remove useless write() operations
3) simplify pwrite() operations before using O_APPEND

Signed-off-by: Dai Shili <daisl.fnst@fujitsu.com>
---
 testcases/kernel/syscalls/pwrite/pwrite04.c | 307 ++++++----------------------
 1 file changed, 66 insertions(+), 241 deletions(-)

diff --git a/testcases/kernel/syscalls/pwrite/pwrite04.c b/testcases/kernel/syscalls/pwrite/pwrite04.c
index 4a2825b..2b5ab35 100644
--- a/testcases/kernel/syscalls/pwrite/pwrite04.c
+++ b/testcases/kernel/syscalls/pwrite/pwrite04.c
@@ -1,267 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *
- *   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
+ * Copyright (c) Linux Test Project, 2021
+ * Copyright (c) International Business Machines  Corp., 2002
+ * ported from SPIE, section2/filesuite/pread_pwrite.c, by Airong Zhang
  */
 
-/*
- * NAME
- *      pwrite04.c (ported from SPIE, section2/filesuite/pread_pwrite.c,
- *      	        by Airong Zhang)
+/*\
+ * [Description]
  *
- * TEST SUMMARY
- *	Test the pwrite() system call with O_APPEND.
+ * Test the pwrite() system call with O_APPEND.
  *
- * USAGE
- *  	pwrite04
+ * Writing 2k data to the file, close it and reopen it with O_APPEND.
  *
+ * POSIX requires that opening a file with the O_APPEND flag should have no effect on the
+ * location at which pwrite() writes data. However, on Linux, if a file is opened with
+ * O_APPEND, pwrite() appends data to the end of the file, regardless of the value of offset.
  */
 
-#define _XOPEN_SOURCE 500
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include "test.h"
-
-char *TCID = "pwrite04";
-int TST_TOTAL = 1;
-int local_flag;
+#include <stdlib.h>
+#include "tst_test.h"
+#include "tst_safe_prw.h"
 
-#define PASSED 1
-#define FAILED 0
+#define K1              1024
+#define K2              (K1 * 2)
+#define K3              (K1 * 3)
+#define DATA_FILE       "pwrite04_file"
 
-int block_cnt = 0;
+static int fd = -1;
+static char *write_buf[2];
 
-#define K1    		1024
-#define K2    		(K1 * 2)
-#define K3    		(K1 * 3)
-#define K4    		(K1 * 4)
-#define K5    		(K1 * 5)
-#define	NBUFS 		4
-#define DATA_FILE	"pwrite04_file"
-
-char name[256], fname[256];
-
-void init_buffers(char *[]);
-void l_seek(int, off_t, int, off_t);
-static void cleanup(void);
-
-int main(int ac, char *av[])
+static void l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
 {
-	int fd;
-	int nbytes;
-	char *wbuf[NBUFS];
-	struct stat statbuf;
-	int lc;
-
-	strcpy(name, DATA_FILE);
-	sprintf(fname, "%s.%d", name, getpid());
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	tst_tmpdir();
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-
-		init_buffers(wbuf);
-		local_flag = PASSED;
-
-		if ((fd = open(fname, O_RDWR | O_CREAT, 0666)) < 0) {
-			tst_resm(TBROK, "open failed: fname = %s, errno = %d",
-				 fname, errno);
-			cleanup();
-		}
-		/*
-		 * pwrite() K1 of data (0's) at offset 0.
-		 */
-		if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) {
-			tst_resm(TFAIL,
-				 "pwrite at 0 failed: nbytes=%d, errno=%d",
-				 nbytes, errno);
-			cleanup();
-		}
-
-		/*
-		 * We should still be at offset 0.
-		 */
-		l_seek(fd, 0, SEEK_CUR, 0);
-
-		/*
-		 * lseek() to a non K boundary, just to be different.
-		 */
-		l_seek(fd, K1 / 2, SEEK_SET, K1 / 2);
-
-		/*
-		 * pwrite() K1 of data (2's) at offset K2.
-		 */
-		if ((nbytes = pwrite(fd, wbuf[2], K1, K2)) != K1) {
-			tst_resm(TFAIL,
-				 "pwrite at K2 failed: nbytes=%d, errno=%d",
-				 nbytes, errno);
-			cleanup();
-		}
-
-		/*
-		 * We should still be at our non K boundary.
-		 */
-		l_seek(fd, 0, SEEK_CUR, K1 / 2);
-
-		/*
-		 * lseek() to an offset of K3.
-		 */
-		l_seek(fd, K3, SEEK_SET, K3);
-
-		/*
-		 * This time use a normal write() of K1 of data (3's) which should
-		 * take place at an offset of K3, moving the file pointer to K4.
-		 */
-		if ((nbytes = write(fd, wbuf[3], K1)) != K1) {
-			tst_resm(TFAIL, "write failed: nbytes=%d, errno=%d",
-				 nbytes, errno);
-			cleanup();
-		}
-
-		/*
-		 * We should be at offset K4.
-		 */
-		l_seek(fd, 0, SEEK_CUR, K4);
-
-		/*
-		 * pwrite() K1 of data (1's) at offset K1.
-		 */
-		if ((nbytes = pwrite(fd, wbuf[1], K1, K1)) != K1) {
-			tst_resm(TFAIL, "pwrite failed: nbytes=%d, errno=%d",
-				 nbytes, errno);
-			cleanup();
-		}
-
-	/*--------------------------------------------------------------*/
-
-		/*
-		 * Now test that O_APPEND takes precedence over any
-		 * offset specified by pwrite(), but that the file
-		 * pointer remains unchanged.  First, close then reopen
-		 * the file and ensure it is already K4 in length and
-		 * set the file pointer to it's midpoint, K2.
-		 */
-		close(fd);
-		if ((fd = open(fname, O_RDWR | O_APPEND, 0666)) < 0) {
-			tst_resm(TBROK, "open failed: fname = %s, errno = %d",
-				 fname, errno);
-			cleanup();
-		}
-		if (fstat(fd, &statbuf) == -1) {
-			tst_resm(TFAIL, "fstat failed: errno = %d", errno);
-			cleanup();
-		}
-		if (statbuf.st_size != K4) {
-			tst_resm(TFAIL, "file size is %ld != K4",
-				 statbuf.st_size);
-			cleanup();
-		}
-		l_seek(fd, K2, SEEK_SET, K2);
-
-		/*
-		 * Finally, pwrite() some K1 of data at offset 0.
-		 * What we should end up with is:
-		 *      -The file pointer should still be at K2.
-		 *      -The data should have been written to the end
-		 *       of the file (O_APPEND) and should be K5 in size.
-		 */
-		if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) {
-			tst_resm(TFAIL,
-				 "pwrite at 0 failed: nbytes=%d, errno=%d",
-				 nbytes, errno);
-
-		}
-		l_seek(fd, 0, SEEK_CUR, K2);
-		if (fstat(fd, &statbuf) == -1) {
-			tst_resm(TFAIL, "fstat failed: errno = %d", errno);
-
-		}
-		if (statbuf.st_size != K5) {
-			tst_resm(TFAIL, "file size is %ld != K4",
-				 statbuf.st_size);
-
-		}
-		tst_resm(TPASS, "O_APPEND test passed.");
-
-	/*------------------------------------------------------------------------*/
-
-		close(fd);
-		unlink(fname);
-	}			/* end for */
-	cleanup();
-	tst_exit();
+	off_t offloc;
 
+	offloc = SAFE_LSEEK(fdesc, offset, whence);
+	if (offloc != checkoff) {
+		tst_brk(TFAIL, "%ld = lseek(%d, %ld, %d) != %ld",
+			offloc, fdesc, offset, whence, checkoff);
+	}
 }
 
-/*------------------------------------------------------------------------*/
-
-/*
- * init_buffers() allocates wbuf[] array
- * as follows:
- * wbuf[0] has 0's, wbuf[1] has 1's, wbuf[2] has 2's, and wbuf[3] has 3's.
- */
-void init_buffers(char *wbuf[])
+static void verify_pwrite(void)
 {
-	int i;
+	struct stat statbuf;
 
-	for (i = 0; i < NBUFS; i++) {
-		wbuf[i] = malloc(K1);
-		if (wbuf[i] == NULL) {
-			tst_brkm(TBROK, NULL, "ib: malloc failed: errno=%d",
-				 errno);
-		}
-		memset(wbuf[i], i, K1);
-	}
+	fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0666);
+	SAFE_PWRITE(1, fd, write_buf[0], K2, 0);
+	SAFE_CLOSE(fd);
+
+	fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_APPEND, 0666);
+	SAFE_FSTAT(fd, &statbuf);
+	if (statbuf.st_size != K2)
+		tst_res(TFAIL, "file size is %ld != K2", statbuf.st_size);
+
+	/* Appends data to the end of the file regardless of offset. */
+	l_seek(fd, K1, SEEK_SET, K1);
+	SAFE_PWRITE(1, fd, write_buf[1], K1, 0);
+	l_seek(fd, 0, SEEK_CUR, K1);
+	SAFE_FSTAT(fd, &statbuf);
+	if (statbuf.st_size != K3)
+		tst_res(TFAIL, "file size is %ld != K3", statbuf.st_size);
+
+	tst_res(TPASS, "O_APPEND test passed.");
+	SAFE_CLOSE(fd);
 }
 
-/*
- * l_seek() is a local front end to lseek().
- * "checkoff" is the offset at which we believe we should be at.
- * Used to validate pwrite doesn't move the offset.
- */
-void l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
+static void setup(void)
 {
-	off_t offloc;
-
-	if ((offloc = lseek(fdesc, offset, whence)) != checkoff) {
-		tst_brkm(TFAIL, NULL,
-			 "(%ld = lseek(%d, %ld, %d)) != %ld) errno = %d",
-			 offloc, fdesc, offset, whence, checkoff, errno);
-	}
+	write_buf[0] = SAFE_MALLOC(K2);
+	memset(write_buf[0], 0, K2);
+	write_buf[1] = SAFE_MALLOC(K1);
+	memset(write_buf[0], 1, K1);
 }
 
-/*
- * cleanup() - Performs all ONE TIME cleanup for this test at
- *             completion or premature exit.
- *
- *	Print test timing stats and errno log if test executed with options.
- *	Close the testfile if still opened.
- *	Remove temporary directory and sub-directories/files under it
- *	created during setup().
- *	Exit the test program with normal exit code.
- */
-void cleanup(void)
+static void cleanup(void)
 {
+	free(write_buf[0]);
+	free(write_buf[1]);
 
-	tst_rmdir();
+	if (fd > -1)
+		SAFE_CLOSE(fd);
 
+	SAFE_UNLINK(DATA_FILE);
 }
+
+static struct tst_test test = {
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = verify_pwrite,
+};
-- 
1.8.3.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

             reply	other threads:[~2021-12-02  9:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-13  0:09 Dai Shili [this message]
2021-12-03  3:17 ` [LTP] [PATCH] syscalls/pwrite04: Convert to new API xuyang2018.jy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1636762161-26777-1-git-send-email-daisl.fnst@fujitsu.com \
    --to=daisl.fnst@fujitsu.com \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.