* [LTP] [PATCH] syscalls/readv02: Convert to new API and merge readv03 into readv02.
@ 2021-07-30 5:48 Dai Shili
2021-08-03 13:43 ` Cyril Hrubis
0 siblings, 1 reply; 5+ messages in thread
From: Dai Shili @ 2021-07-30 5:48 UTC (permalink / raw)
To: ltp
1) merge readv03 into readv02
2) use tst_get_bad_addr() API
3) use TST_EXP_FAIL2 macro
Signed-off-by: Dai Shili <daisl.fnst@fujitsu.com>
---
runtest/syscalls | 1 -
testcases/kernel/syscalls/readv/.gitignore | 1 -
testcases/kernel/syscalls/readv/readv02.c | 331 ++++++++++-------------------
testcases/kernel/syscalls/readv/readv03.c | 53 -----
4 files changed, 108 insertions(+), 278 deletions(-)
delete mode 100644 testcases/kernel/syscalls/readv/readv03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index b379b2d..9c3b510 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1085,7 +1085,6 @@ readlinkat02 readlinkat02
readv01 readv01
readv02 readv02
-readv03 readv03
realpath01 realpath01
diff --git a/testcases/kernel/syscalls/readv/.gitignore b/testcases/kernel/syscalls/readv/.gitignore
index c4aa61e..a532741 100644
--- a/testcases/kernel/syscalls/readv/.gitignore
+++ b/testcases/kernel/syscalls/readv/.gitignore
@@ -1,3 +1,2 @@
/readv01
/readv02
-/readv03
diff --git a/testcases/kernel/syscalls/readv/readv02.c b/testcases/kernel/syscalls/readv/readv02.c
index aa40e2c..aaadae0 100644
--- a/testcases/kernel/syscalls/readv/readv02.c
+++ b/testcases/kernel/syscalls/readv/readv02.c
@@ -1,198 +1,130 @@
+// 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) Bull S.A. 2001
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * 05/2002 Ported by Jacky Malcles
*/
-/*
- * NAME
- * readv02.c
- *
+/*\
* DESCRIPTION
- * Testcase to check the error conditions of the readv(2) system call.
+ * test 1:
+ * The sum of the iov_len values overflows an ssize_t value, expect an EINVAL.
*
- * CALLS
- * readv()
+ * test 2:
+ * Buf is outside the accessible address space, expect an EFAULT.
*
- * ALGORITHM
- * Create a IO vector, and attempt to readv() various components of it.
+ * test 3:
+ * The vector count iovcnt is less than zero, expect an EINVAL.
*
- * USAGE
- * readv02
+ * test 4:
+ * The parameter passed to read is a directory, check if the errno is
+ * set to EISDIR.
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
+ * test 5:
+ * Read with an invalid file descriptor, and expect an EBADF.
*/
-#include <sys/types.h>
+
#include <sys/uio.h>
#include <fcntl.h>
-#include <sys/mman.h>
#include <memory.h>
-#include <errno.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-#define K_1 1024
-#define M_1 K_1 * K_1
-#define G_1 M_1 * K_1
-
-#define NBUFS 4
-#define CHUNK 64
-#define MAX_IOVEC 16
-#define DATA_FILE "readv_data_file"
-
-char buf1[K_1], buf2[K_1], buf3[K_1];
-
-struct iovec rd_iovec[MAX_IOVEC] = {
- /* iov_base *//* iov_len */
+#include "tst_test.h"
+
+#define K_1 1024
+#define M_1 (K_1 * K_1)
+#define G_1 (M_1 * K_1)
+#define MODES 0700
+
+#define NBUFS 4
+#define CHUNK 64
+#define MAX_IOVEC 16
+
+static int badfd = -1;
+static int fd[4] = {-1, -1, -1, -1};
+static char buf1[K_1], buf2[K_1], buf3[K_1];
+const char *TEST_DIR = "test_dir";
+const char *TEST_FILE[3] = {"file1", "file2", "file3"};
+char *buf_list[NBUFS];
- /* Test case #1 */
+static struct iovec rd_iovec[MAX_IOVEC] = {
{buf2, -1},
{(buf2 + CHUNK), CHUNK},
{(buf2 + CHUNK * 2), CHUNK},
-
- /* Test case #2 */
{(buf2 + CHUNK * 3), G_1},
{(buf2 + CHUNK * 4), G_1},
{(buf2 + CHUNK * 5), G_1},
-
- /* Test case #3 */
{(caddr_t) - 1, CHUNK},
{(buf2 + CHUNK * 6), CHUNK},
{(buf2 + CHUNK * 8), CHUNK},
-
- /* Test case #4 */
- {(buf2 + CHUNK * 9), CHUNK}
+ {(buf2 + CHUNK * 9), CHUNK},
+ {buf1, K_1}
};
-char f_name[K_1];
-
-int fd[4];
-char *buf_list[NBUFS];
-
-char *TCID = "readv02";
-int TST_TOTAL = 1;
-
-char *bad_addr = 0;
+static struct tcase {
+ int *fd;
+ void *buf;
+ int count;
+ int exp_error;
+} tcases[] = {
+ {&fd[0], rd_iovec, 1, EINVAL},
+ {&fd[1], rd_iovec + 6, 3, EFAULT},
+ {&fd[2], rd_iovec + 10, -1, EINVAL},
+ {&fd[3], rd_iovec + 10, 1, EISDIR},
+ {&badfd, rd_iovec + 9, 3, EBADF},
+};
-int init_buffs(char **);
-int fill_mem(char *, int, int);
-long l_seek(int, long, int);
-char *getenv();
-void setup();
-void cleanup();
-int main(int ac, char **av)
+void fill_mem(char *c_ptr, int c1, int c2)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ int count;
- /* The following loop checks looping state if -i option given */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
+ for (count = 1; count <= K_1 / CHUNK; count++) {
+ if (count & 0x01) /* if odd */
+ memset(c_ptr, c1, CHUNK);
+ else /* if even */
+ memset(c_ptr, c2, CHUNK);
+ }
+ return;
+}
- /* reset tst_count in case we are looping */
- tst_count = 0;
+void init_buffs(char *pbufs[])
+{
+ int i;
-//test1:
- if (readv(fd[0], rd_iovec, 1) < 0) {
- if (errno != EINVAL) {
- tst_resm(TFAIL, "readv() set an illegal errno:"
- " expected: EINVAL, got %d", errno);
- } else {
- tst_resm(TPASS, "got EINVAL");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
+ for (i = 0; pbufs[i] != NULL; i++) {
+ switch (i) {
+ case 0:
+ case 1:
+ fill_mem(pbufs[i], 0, 1);
+ break;
+ case 2:
+ fill_mem(pbufs[i], 1, 0);
+ break;
+ default:
+ tst_brk(TBROK, "Error in init_buffs function");
}
+ }
+ return;
+}
-//test2:
- l_seek(fd[0], CHUNK * 6, 0);
- if (readv(fd[0], (rd_iovec + 6), 3) < 0) {
- if (errno != EFAULT) {
- tst_resm(TFAIL, "expected errno = EFAULT, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EFAULT");
- }
- if (memcmp((buf_list[0] + CHUNK * 6),
- (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) {
- tst_resm(TFAIL, "Error: readv() partially "
- "overlaid buf[2]");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
+static void verify_readv(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
-//test3:
- if (readv(fd[1], (rd_iovec + 9), 1) < 0) {
- if (errno != EBADF) {
- tst_resm(TFAIL, "expected errno = EBADF, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EBADF");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
+ TST_EXP_FAIL2(readv(*tc->fd, tc->buf, tc->count), tc->exp_error,
+ "readv(%d, %p, %d)", *tc->fd, tc->buf, tc->count);
-//test4:
- l_seek(fd[0], CHUNK * 10, 0);
- if (readv(fd[0], (rd_iovec + 10), -1) < 0) {
- if (errno != EINVAL) {
- tst_resm(TFAIL, "expected errno = EINVAL, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EINVAL");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
+ if (tc->exp_error == EFAULT) {
+ if (memcmp((buf_list[0] + CHUNK * 6),
+ (buf_list[1] + CHUNK * 6), CHUNK * 3)) {
+ tst_res(TFAIL, "Error: readv() partially overlaid buf[2]");
}
-
}
- close(fd[0]);
- close(fd[1]);
- cleanup();
- tst_exit();
-
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
void setup(void)
{
- int nbytes;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* make a temporary directory and cd to it */
- tst_tmpdir();
+ int i;
buf_list[0] = buf1;
buf_list[1] = buf2;
@@ -201,84 +133,37 @@ void setup(void)
init_buffs(buf_list);
- sprintf(f_name, "%s.%d", DATA_FILE, getpid());
+ for (i = 0; i < 3; i++) {
+ fd[i] = SAFE_OPEN(TEST_FILE[i], O_WRONLY | O_CREAT, 0666);
+ SAFE_WRITE(1, fd[i], buf_list[2], K_1);
- if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
- tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
- "errno = %d", f_name, errno);
- } else {
- if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) {
- tst_brkm(TBROK, cleanup, "write failed: nbytes "
- "= %d " "errno = %d", nbytes, errno);
- }
- }
+ SAFE_CLOSE(fd[i]);
- SAFE_CLOSE(cleanup, fd[0]);
-
- if ((fd[0] = open(f_name, O_RDONLY, 0666)) < 0) {
- tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
- "errno = %d", f_name, errno);
+ fd[i] = SAFE_OPEN(TEST_FILE[i], O_RDONLY, 0666);
}
+ SAFE_LSEEK(fd[1], CHUNK * 6, 0);
+ SAFE_LSEEK(fd[2], CHUNK * 10, 0);
- fd[1] = -1; /* Invalid file descriptor */
+ rd_iovec[6].iov_base = tst_get_bad_addr(NULL);
- bad_addr = mmap(0, 1, PROT_NONE,
- MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
- if (bad_addr == MAP_FAILED) {
- tst_brkm(TBROK, cleanup, "mmap failed");
- }
- rd_iovec[6].iov_base = bad_addr;
+ SAFE_MKDIR(TEST_DIR, MODES);
+ fd[3] = SAFE_OPEN(TEST_DIR, O_RDONLY);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
- SAFE_UNLINK(NULL, f_name);
- tst_rmdir();
-
-}
-
-int init_buffs(char *pbufs[])
+static void cleanup(void)
{
int i;
- for (i = 0; pbufs[i] != NULL; i++) {
- switch (i) {
- case 0:
- /*FALLTHROUGH*/ case 1:
- fill_mem(pbufs[i], 0, 1);
- break;
-
- case 2:
- fill_mem(pbufs[i], 1, 0);
- break;
-
- default:
- tst_brkm(TBROK, cleanup, "Error in init_buffs()");
- }
- }
- return 0;
-}
-
-int fill_mem(char *c_ptr, int c1, int c2)
-{
- int count;
-
- for (count = 1; count <= K_1 / CHUNK; count++) {
- if (count & 0x01) { /* if odd */
- memset(c_ptr, c1, CHUNK);
- } else { /* if even */
- memset(c_ptr, c2, CHUNK);
- }
+ for (i = 0; i < 4; i++) {
+ if (fd[i] > 0)
+ SAFE_CLOSE(fd[i]);
}
- return 0;
}
-long l_seek(int fdesc, long offset, int whence)
-{
- SAFE_LSEEK(cleanup, fdesc, offset, whence);
- return 0;
-}
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcases),
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_readv,
+};
diff --git a/testcases/kernel/syscalls/readv/readv03.c b/testcases/kernel/syscalls/readv/readv03.c
deleted file mode 100644
index 8f5cddf..0000000
--- a/testcases/kernel/syscalls/readv/readv03.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) Bull S.A. 2001
- * Copyright (c) International Business Machines Corp., 2001
- * 05/2002 Ported by Jacky Malcles
- */
-
-/*\
- * [Description]
- *
- * Testcase to check EISDIR error when fd refers to a directory.
- */
-
-#include <sys/uio.h>
-#include <fcntl.h>
-#include "tst_test.h"
-
-#define K_1 1024
-#define MODES S_IRWXU
-
-static char buf1[K_1];
-
-static struct iovec rd_iovec[1] = {
- {buf1, K_1}
-};
-
-const char *TEST_DIR = "alpha";
-static int fd;
-
-static void verify_readv(void)
-{
- TST_EXP_FAIL2(readv(fd, rd_iovec, 1), EISDIR,
- "readv() got EISDIR");
-}
-
-void setup(void)
-{
- SAFE_MKDIR(TEST_DIR, MODES);
- fd = SAFE_OPEN(TEST_DIR, O_RDONLY);
-}
-
-static void cleanup(void)
-{
- if (fd > 0)
- SAFE_CLOSE(fd);
-}
-
-static struct tst_test test = {
- .needs_tmpdir = 1,
- .setup = setup,
- .cleanup = cleanup,
- .test_all = verify_readv,
-};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [LTP] [PATCH] syscalls/readv02: Convert to new API and merge readv03 into readv02.
2021-07-30 5:48 [LTP] [PATCH] syscalls/readv02: Convert to new API and merge readv03 into readv02 Dai Shili
@ 2021-08-03 13:43 ` Cyril Hrubis
2021-08-04 9:37 ` [LTP] 回复: " daisl.fnst
2021-08-15 11:02 ` [LTP] [PATCH v2] " Dai Shili
0 siblings, 2 replies; 5+ messages in thread
From: Cyril Hrubis @ 2021-08-03 13:43 UTC (permalink / raw)
To: ltp
Hi!
> - /* Test case #1 */
> +static struct iovec rd_iovec[MAX_IOVEC] = {
> {buf2, -1},
> {(buf2 + CHUNK), CHUNK},
> {(buf2 + CHUNK * 2), CHUNK},
> -
> - /* Test case #2 */
> {(buf2 + CHUNK * 3), G_1},
> {(buf2 + CHUNK * 4), G_1},
> {(buf2 + CHUNK * 5), G_1},
> -
> - /* Test case #3 */
> {(caddr_t) - 1, CHUNK},
> {(buf2 + CHUNK * 6), CHUNK},
> {(buf2 + CHUNK * 8), CHUNK},
> -
> - /* Test case #4 */
> - {(buf2 + CHUNK * 9), CHUNK}
> + {(buf2 + CHUNK * 9), CHUNK},
> + {buf1, K_1}
> };
It would be much easier to read the code if we split this iovec so that
each test has it's own structure. There is absolutely no reason to keep
them all together like that.
I.e. we will have it as:
static struct iovec invalid_iovec[] = {
{buf, -1},
{buf + CHUNK, CHUNK},
{buf + 2*CHUNK, CHUNK},
};
static struct iovec large_iovec[] = {
{buf2, G_1},
{buf2 + CHUNK, G_1},
{buf2 + CHUNK*2, G_1},
};
static struct iovec efault_iovec[] = {
{NULL, CHUNK},
{buf + CHUNK, CHUNK},
{buf + 2*CHUNK, CHUNK},
};
static struct iovec valid_iovec[] = {
{buf, CHUNK},
};
Also we can use the valid iovec for both EISDIR and EBADFD.
static void setup(void)
{
...
efault_iovec[0].iov_base = tst_get_bad_addr(NULL);
...
}
Also I do not think that we need three buffers, the buf3 is completely
unused and there is no point in having special buffer for badfd test
either.
> -char f_name[K_1];
> -
> -int fd[4];
> -char *buf_list[NBUFS];
> -
> -char *TCID = "readv02";
> -int TST_TOTAL = 1;
> -
> -char *bad_addr = 0;
> +static struct tcase {
> + int *fd;
> + void *buf;
> + int count;
> + int exp_error;
> +} tcases[] = {
> + {&fd[0], rd_iovec, 1, EINVAL},
> + {&fd[1], rd_iovec + 6, 3, EFAULT},
> + {&fd[2], rd_iovec + 10, -1, EINVAL},
> + {&fd[3], rd_iovec + 10, 1, EISDIR},
> + {&badfd, rd_iovec + 9, 3, EBADF},
> +};
>
> -int init_buffs(char **);
> -int fill_mem(char *, int, int);
> -long l_seek(int, long, int);
> -char *getenv();
> -void setup();
> -void cleanup();
>
> -int main(int ac, char **av)
> +void fill_mem(char *c_ptr, int c1, int c2)
> {
> - int lc;
> -
> - tst_parse_opts(ac, av, NULL, NULL);
> -
> - setup();
> + int count;
>
> - /* The following loop checks looping state if -i option given */
> - for (lc = 0; TEST_LOOPING(lc); lc++) {
> + for (count = 1; count <= K_1 / CHUNK; count++) {
> + if (count & 0x01) /* if odd */
> + memset(c_ptr, c1, CHUNK);
> + else /* if even */
> + memset(c_ptr, c2, CHUNK);
> + }
> + return;
> +}
>
> - /* reset tst_count in case we are looping */
> - tst_count = 0;
> +void init_buffs(char *pbufs[])
> +{
> + int i;
>
> -//test1:
> - if (readv(fd[0], rd_iovec, 1) < 0) {
> - if (errno != EINVAL) {
> - tst_resm(TFAIL, "readv() set an illegal errno:"
> - " expected: EINVAL, got %d", errno);
> - } else {
> - tst_resm(TPASS, "got EINVAL");
> - }
> - } else {
> - tst_resm(TFAIL, "Error: readv returned a positive "
> - "value");
> + for (i = 0; pbufs[i] != NULL; i++) {
> + switch (i) {
> + case 0:
> + case 1:
> + fill_mem(pbufs[i], 0, 1);
> + break;
> + case 2:
> + fill_mem(pbufs[i], 1, 0);
> + break;
> + default:
> + tst_brk(TBROK, "Error in init_buffs function");
> }
> + }
> + return;
> +}
>
> -//test2:
> - l_seek(fd[0], CHUNK * 6, 0);
> - if (readv(fd[0], (rd_iovec + 6), 3) < 0) {
> - if (errno != EFAULT) {
> - tst_resm(TFAIL, "expected errno = EFAULT, "
> - "got %d", errno);
> - } else {
> - tst_resm(TPASS, "got EFAULT");
> - }
> - if (memcmp((buf_list[0] + CHUNK * 6),
> - (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) {
> - tst_resm(TFAIL, "Error: readv() partially "
> - "overlaid buf[2]");
> - }
> - } else {
> - tst_resm(TFAIL, "Error: readv returned a positive "
> - "value");
> - }
> +static void verify_readv(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
>
> -//test3:
> - if (readv(fd[1], (rd_iovec + 9), 1) < 0) {
> - if (errno != EBADF) {
> - tst_resm(TFAIL, "expected errno = EBADF, "
> - "got %d", errno);
> - } else {
> - tst_resm(TPASS, "got EBADF");
> - }
> - } else {
> - tst_resm(TFAIL, "Error: readv returned a positive "
> - "value");
> - }
> + TST_EXP_FAIL2(readv(*tc->fd, tc->buf, tc->count), tc->exp_error,
> + "readv(%d, %p, %d)", *tc->fd, tc->buf, tc->count);
>
> -//test4:
> - l_seek(fd[0], CHUNK * 10, 0);
> - if (readv(fd[0], (rd_iovec + 10), -1) < 0) {
> - if (errno != EINVAL) {
> - tst_resm(TFAIL, "expected errno = EINVAL, "
> - "got %d", errno);
> - } else {
> - tst_resm(TPASS, "got EINVAL");
> - }
> - } else {
> - tst_resm(TFAIL, "Error: readv returned a positive "
> - "value");
> + if (tc->exp_error == EFAULT) {
> + if (memcmp((buf_list[0] + CHUNK * 6),
> + (buf_list[1] + CHUNK * 6), CHUNK * 3)) {
> + tst_res(TFAIL, "Error: readv() partially overlaid buf[2]");
> }
> -
> }
> - close(fd[0]);
> - close(fd[1]);
> - cleanup();
> - tst_exit();
> -
> }
>
> -/*
> - * setup() - performs all ONE TIME setup for this test.
> - */
> void setup(void)
> {
> - int nbytes;
> -
> - tst_sig(NOFORK, DEF_HANDLER, cleanup);
> -
> - TEST_PAUSE;
> -
> - /* make a temporary directory and cd to it */
> - tst_tmpdir();
> + int i;
>
> buf_list[0] = buf1;
> buf_list[1] = buf2;
> @@ -201,84 +133,37 @@ void setup(void)
>
> init_buffs(buf_list);
>
> - sprintf(f_name, "%s.%d", DATA_FILE, getpid());
> + for (i = 0; i < 3; i++) {
> + fd[i] = SAFE_OPEN(TEST_FILE[i], O_WRONLY | O_CREAT, 0666);
> + SAFE_WRITE(1, fd[i], buf_list[2], K_1);
>
> - if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
> - tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
> - "errno = %d", f_name, errno);
> - } else {
> - if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) {
> - tst_brkm(TBROK, cleanup, "write failed: nbytes "
> - "= %d " "errno = %d", nbytes, errno);
> - }
> - }
> + SAFE_CLOSE(fd[i]);
>
> - SAFE_CLOSE(cleanup, fd[0]);
> -
> - if ((fd[0] = open(f_name, O_RDONLY, 0666)) < 0) {
> - tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
> - "errno = %d", f_name, errno);
> + fd[i] = SAFE_OPEN(TEST_FILE[i], O_RDONLY, 0666);
> }
> + SAFE_LSEEK(fd[1], CHUNK * 6, 0);
> + SAFE_LSEEK(fd[2], CHUNK * 10, 0);
Does these readv calls actually read anyting?
Because as far as I can tell they just fail without actually reading
anything, so there is no point in intializing the buffers and also there
is no point in having three different files opened for the test either.
> - fd[1] = -1; /* Invalid file descriptor */
> + rd_iovec[6].iov_base = tst_get_bad_addr(NULL);
>
> - bad_addr = mmap(0, 1, PROT_NONE,
> - MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
> - if (bad_addr == MAP_FAILED) {
> - tst_brkm(TBROK, cleanup, "mmap failed");
> - }
> - rd_iovec[6].iov_base = bad_addr;
> + SAFE_MKDIR(TEST_DIR, MODES);
> + fd[3] = SAFE_OPEN(TEST_DIR, O_RDONLY);
> }
>
> -/*
> - * cleanup() - performs all ONE TIME cleanup for this test at
> - * completion or premature exit.
> - */
> -void cleanup(void)
> -{
> - SAFE_UNLINK(NULL, f_name);
> - tst_rmdir();
> -
> -}
> -
> -int init_buffs(char *pbufs[])
> +static void cleanup(void)
> {
> int i;
>
> - for (i = 0; pbufs[i] != NULL; i++) {
> - switch (i) {
> - case 0:
> - /*FALLTHROUGH*/ case 1:
> - fill_mem(pbufs[i], 0, 1);
> - break;
> -
> - case 2:
> - fill_mem(pbufs[i], 1, 0);
> - break;
> -
> - default:
> - tst_brkm(TBROK, cleanup, "Error in init_buffs()");
> - }
> - }
> - return 0;
> -}
> -
> -int fill_mem(char *c_ptr, int c1, int c2)
> -{
> - int count;
> -
> - for (count = 1; count <= K_1 / CHUNK; count++) {
> - if (count & 0x01) { /* if odd */
> - memset(c_ptr, c1, CHUNK);
> - } else { /* if even */
> - memset(c_ptr, c2, CHUNK);
> - }
> + for (i = 0; i < 4; i++) {
> + if (fd[i] > 0)
> + SAFE_CLOSE(fd[i]);
> }
> - return 0;
> }
>
> -long l_seek(int fdesc, long offset, int whence)
> -{
> - SAFE_LSEEK(cleanup, fdesc, offset, whence);
> - return 0;
> -}
> +static struct tst_test test = {
> + .tcnt = ARRAY_SIZE(tcases),
> + .needs_tmpdir = 1,
> + .setup = setup,
> + .cleanup = cleanup,
> + .test = verify_readv,
> +};
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 5+ messages in thread
* [LTP] 回复: [PATCH] syscalls/readv02: Convert to new API and merge readv03 into readv02.
2021-08-03 13:43 ` Cyril Hrubis
@ 2021-08-04 9:37 ` daisl.fnst
2021-08-15 11:02 ` [LTP] [PATCH v2] " Dai Shili
1 sibling, 0 replies; 5+ messages in thread
From: daisl.fnst @ 2021-08-04 9:37 UTC (permalink / raw)
To: ltp
Hi Cyril,
Thank you very much for your comments. I will send a v2.
> -----????-----
> ???: Cyril Hrubis <chrubis@suse.cz>
> ????: 2021?8?3? 21:44
> ???: Dai, Shili/? ?? <daisl.fnst@fujitsu.com>
> ??: ltp@lists.linux.it
> ??: Re: [LTP] [PATCH] syscalls/readv02: Convert to new API and merge
> readv03 into readv02.
>
> Hi!
> > - /* Test case #1 */
> > +static struct iovec rd_iovec[MAX_IOVEC] = {
> > {buf2, -1},
> > {(buf2 + CHUNK), CHUNK},
> > {(buf2 + CHUNK * 2), CHUNK},
> > -
> > - /* Test case #2 */
> > {(buf2 + CHUNK * 3), G_1},
> > {(buf2 + CHUNK * 4), G_1},
> > {(buf2 + CHUNK * 5), G_1},
> > -
> > - /* Test case #3 */
> > {(caddr_t) - 1, CHUNK},
> > {(buf2 + CHUNK * 6), CHUNK},
> > {(buf2 + CHUNK * 8), CHUNK},
> > -
> > - /* Test case #4 */
> > - {(buf2 + CHUNK * 9), CHUNK}
> > + {(buf2 + CHUNK * 9), CHUNK},
> > + {buf1, K_1}
> > };
>
> It would be much easier to read the code if we split this iovec so that each test
> has it's own structure. There is absolutely no reason to keep them all together
> like that.
>
> I.e. we will have it as:
>
> static struct iovec invalid_iovec[] = {
> {buf, -1},
> {buf + CHUNK, CHUNK},
> {buf + 2*CHUNK, CHUNK},
> };
>
> static struct iovec large_iovec[] = {
> {buf2, G_1},
> {buf2 + CHUNK, G_1},
> {buf2 + CHUNK*2, G_1},
> };
>
> static struct iovec efault_iovec[] = {
> {NULL, CHUNK},
> {buf + CHUNK, CHUNK},
> {buf + 2*CHUNK, CHUNK},
> };
>
> static struct iovec valid_iovec[] = {
> {buf, CHUNK},
> };
>
> Also we can use the valid iovec for both EISDIR and EBADFD.
>
> static void setup(void)
> {
> ...
> efault_iovec[0].iov_base = tst_get_bad_addr(NULL);
> ...
> }
>
> Also I do not think that we need three buffers, the buf3 is completely unused
> and there is no point in having special buffer for badfd test either.
>
> > -char f_name[K_1];
> > -
> > -int fd[4];
> > -char *buf_list[NBUFS];
> > -
> > -char *TCID = "readv02";
> > -int TST_TOTAL = 1;
> > -
> > -char *bad_addr = 0;
> > +static struct tcase {
> > + int *fd;
> > + void *buf;
> > + int count;
> > + int exp_error;
> > +} tcases[] = {
> > + {&fd[0], rd_iovec, 1, EINVAL},
> > + {&fd[1], rd_iovec + 6, 3, EFAULT},
> > + {&fd[2], rd_iovec + 10, -1, EINVAL},
> > + {&fd[3], rd_iovec + 10, 1, EISDIR},
> > + {&badfd, rd_iovec + 9, 3, EBADF},
> > +};
> >
> > -int init_buffs(char **);
> > -int fill_mem(char *, int, int);
> > -long l_seek(int, long, int);
> > -char *getenv();
> > -void setup();
> > -void cleanup();
> >
> > -int main(int ac, char **av)
> > +void fill_mem(char *c_ptr, int c1, int c2)
> > {
> > - int lc;
> > -
> > - tst_parse_opts(ac, av, NULL, NULL);
> > -
> > - setup();
> > + int count;
> >
> > - /* The following loop checks looping state if -i option given */
> > - for (lc = 0; TEST_LOOPING(lc); lc++) {
> > + for (count = 1; count <= K_1 / CHUNK; count++) {
> > + if (count & 0x01) /* if odd */
> > + memset(c_ptr, c1, CHUNK);
> > + else /* if even */
> > + memset(c_ptr, c2, CHUNK);
> > + }
> > + return;
> > +}
> >
> > - /* reset tst_count in case we are looping */
> > - tst_count = 0;
> > +void init_buffs(char *pbufs[])
> > +{
> > + int i;
> >
> > -//test1:
> > - if (readv(fd[0], rd_iovec, 1) < 0) {
> > - if (errno != EINVAL) {
> > - tst_resm(TFAIL, "readv() set an illegal errno:"
> > - " expected: EINVAL, got %d", errno);
> > - } else {
> > - tst_resm(TPASS, "got EINVAL");
> > - }
> > - } else {
> > - tst_resm(TFAIL, "Error: readv returned a positive "
> > - "value");
> > + for (i = 0; pbufs[i] != NULL; i++) {
> > + switch (i) {
> > + case 0:
> > + case 1:
> > + fill_mem(pbufs[i], 0, 1);
> > + break;
> > + case 2:
> > + fill_mem(pbufs[i], 1, 0);
> > + break;
> > + default:
> > + tst_brk(TBROK, "Error in init_buffs function");
> > }
> > + }
> > + return;
> > +}
> >
> > -//test2:
> > - l_seek(fd[0], CHUNK * 6, 0);
> > - if (readv(fd[0], (rd_iovec + 6), 3) < 0) {
> > - if (errno != EFAULT) {
> > - tst_resm(TFAIL, "expected errno = EFAULT, "
> > - "got %d", errno);
> > - } else {
> > - tst_resm(TPASS, "got EFAULT");
> > - }
> > - if (memcmp((buf_list[0] + CHUNK * 6),
> > - (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) {
> > - tst_resm(TFAIL, "Error: readv() partially "
> > - "overlaid buf[2]");
> > - }
> > - } else {
> > - tst_resm(TFAIL, "Error: readv returned a positive "
> > - "value");
> > - }
> > +static void verify_readv(unsigned int n) {
> > + struct tcase *tc = &tcases[n];
> >
> > -//test3:
> > - if (readv(fd[1], (rd_iovec + 9), 1) < 0) {
> > - if (errno != EBADF) {
> > - tst_resm(TFAIL, "expected errno = EBADF, "
> > - "got %d", errno);
> > - } else {
> > - tst_resm(TPASS, "got EBADF");
> > - }
> > - } else {
> > - tst_resm(TFAIL, "Error: readv returned a positive "
> > - "value");
> > - }
> > + TST_EXP_FAIL2(readv(*tc->fd, tc->buf, tc->count), tc->exp_error,
> > + "readv(%d, %p, %d)", *tc->fd, tc->buf, tc->count);
> >
> > -//test4:
> > - l_seek(fd[0], CHUNK * 10, 0);
> > - if (readv(fd[0], (rd_iovec + 10), -1) < 0) {
> > - if (errno != EINVAL) {
> > - tst_resm(TFAIL, "expected errno = EINVAL, "
> > - "got %d", errno);
> > - } else {
> > - tst_resm(TPASS, "got EINVAL");
> > - }
> > - } else {
> > - tst_resm(TFAIL, "Error: readv returned a positive "
> > - "value");
> > + if (tc->exp_error == EFAULT) {
> > + if (memcmp((buf_list[0] + CHUNK * 6),
> > + (buf_list[1] + CHUNK * 6), CHUNK * 3)) {
> > + tst_res(TFAIL, "Error: readv() partially overlaid buf[2]");
> > }
> > -
> > }
> > - close(fd[0]);
> > - close(fd[1]);
> > - cleanup();
> > - tst_exit();
> > -
> > }
> >
> > -/*
> > - * setup() - performs all ONE TIME setup for this test.
> > - */
> > void setup(void)
> > {
> > - int nbytes;
> > -
> > - tst_sig(NOFORK, DEF_HANDLER, cleanup);
> > -
> > - TEST_PAUSE;
> > -
> > - /* make a temporary directory and cd to it */
> > - tst_tmpdir();
> > + int i;
> >
> > buf_list[0] = buf1;
> > buf_list[1] = buf2;
> > @@ -201,84 +133,37 @@ void setup(void)
> >
> > init_buffs(buf_list);
> >
> > - sprintf(f_name, "%s.%d", DATA_FILE, getpid());
> > + for (i = 0; i < 3; i++) {
> > + fd[i] = SAFE_OPEN(TEST_FILE[i], O_WRONLY | O_CREAT, 0666);
> > + SAFE_WRITE(1, fd[i], buf_list[2], K_1);
> >
> > - if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
> > - tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
> > - "errno = %d", f_name, errno);
> > - } else {
> > - if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) {
> > - tst_brkm(TBROK, cleanup, "write failed: nbytes "
> > - "= %d " "errno = %d", nbytes, errno);
> > - }
> > - }
> > + SAFE_CLOSE(fd[i]);
> >
> > - SAFE_CLOSE(cleanup, fd[0]);
> > -
> > - if ((fd[0] = open(f_name, O_RDONLY, 0666)) < 0) {
> > - tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
> > - "errno = %d", f_name, errno);
> > + fd[i] = SAFE_OPEN(TEST_FILE[i], O_RDONLY, 0666);
> > }
> > + SAFE_LSEEK(fd[1], CHUNK * 6, 0);
> > + SAFE_LSEEK(fd[2], CHUNK * 10, 0);
>
> Does these readv calls actually read anyting?
>
> Because as far as I can tell they just fail without actually reading anything, so
> there is no point in intializing the buffers and also there is no point in having
> three different files opened for the test either.
>
> > - fd[1] = -1; /* Invalid file descriptor */
> > + rd_iovec[6].iov_base = tst_get_bad_addr(NULL);
> >
> > - bad_addr = mmap(0, 1, PROT_NONE,
> > - MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
> > - if (bad_addr == MAP_FAILED) {
> > - tst_brkm(TBROK, cleanup, "mmap failed");
> > - }
> > - rd_iovec[6].iov_base = bad_addr;
> > + SAFE_MKDIR(TEST_DIR, MODES);
> > + fd[3] = SAFE_OPEN(TEST_DIR, O_RDONLY);
> > }
> >
> > -/*
> > - * cleanup() - performs all ONE TIME cleanup for this test at
> > - * completion or premature exit.
> > - */
> > -void cleanup(void)
> > -{
> > - SAFE_UNLINK(NULL, f_name);
> > - tst_rmdir();
> > -
> > -}
> > -
> > -int init_buffs(char *pbufs[])
> > +static void cleanup(void)
> > {
> > int i;
> >
> > - for (i = 0; pbufs[i] != NULL; i++) {
> > - switch (i) {
> > - case 0:
> > - /*FALLTHROUGH*/ case 1:
> > - fill_mem(pbufs[i], 0, 1);
> > - break;
> > -
> > - case 2:
> > - fill_mem(pbufs[i], 1, 0);
> > - break;
> > -
> > - default:
> > - tst_brkm(TBROK, cleanup, "Error in init_buffs()");
> > - }
> > - }
> > - return 0;
> > -}
> > -
> > -int fill_mem(char *c_ptr, int c1, int c2) -{
> > - int count;
> > -
> > - for (count = 1; count <= K_1 / CHUNK; count++) {
> > - if (count & 0x01) { /* if odd */
> > - memset(c_ptr, c1, CHUNK);
> > - } else { /* if even */
> > - memset(c_ptr, c2, CHUNK);
> > - }
> > + for (i = 0; i < 4; i++) {
> > + if (fd[i] > 0)
> > + SAFE_CLOSE(fd[i]);
> > }
> > - return 0;
> > }
> >
> > -long l_seek(int fdesc, long offset, int whence) -{
> > - SAFE_LSEEK(cleanup, fdesc, offset, whence);
> > - return 0;
> > -}
> > +static struct tst_test test = {
> > + .tcnt = ARRAY_SIZE(tcases),
> > + .needs_tmpdir = 1,
> > + .setup = setup,
> > + .cleanup = cleanup,
> > + .test = verify_readv,
> > +};
>
> --
> Cyril Hrubis
> chrubis@suse.cz
^ permalink raw reply [flat|nested] 5+ messages in thread
* [LTP] [PATCH v2] syscalls/readv02: Convert to new API and merge readv03 into readv02
2021-08-03 13:43 ` Cyril Hrubis
2021-08-04 9:37 ` [LTP] 回复: " daisl.fnst
@ 2021-08-15 11:02 ` Dai Shili
2021-08-31 15:55 ` Cyril Hrubis
1 sibling, 1 reply; 5+ messages in thread
From: Dai Shili @ 2021-08-15 11:02 UTC (permalink / raw)
To: ltp
1) merge readv03 into readv02
2) use tst_get_bad_addr() API
3) use TST_EXP_FAIL2 macro
Signed-off-by: Dai Shili <daisl.fnst@fujitsu.com>
---
runtest/syscalls | 1 -
testcases/kernel/syscalls/readv/.gitignore | 1 -
testcases/kernel/syscalls/readv/readv02.c | 327 +++++++----------------------
testcases/kernel/syscalls/readv/readv03.c | 53 -----
4 files changed, 79 insertions(+), 303 deletions(-)
delete mode 100644 testcases/kernel/syscalls/readv/readv03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 9af5aa5..cb04a88 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1085,7 +1085,6 @@ readlinkat02 readlinkat02
readv01 readv01
readv02 readv02
-readv03 readv03
realpath01 realpath01
diff --git a/testcases/kernel/syscalls/readv/.gitignore b/testcases/kernel/syscalls/readv/.gitignore
index c4aa61e..a532741 100644
--- a/testcases/kernel/syscalls/readv/.gitignore
+++ b/testcases/kernel/syscalls/readv/.gitignore
@@ -1,3 +1,2 @@
/readv01
/readv02
-/readv03
diff --git a/testcases/kernel/syscalls/readv/readv02.c b/testcases/kernel/syscalls/readv/readv02.c
index aa40e2c..9a26e50 100644
--- a/testcases/kernel/syscalls/readv/readv02.c
+++ b/testcases/kernel/syscalls/readv/readv02.c
@@ -1,284 +1,115 @@
+// 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) Bull S.A. 2001
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * 05/2002 Ported by Jacky Malcles
*/
-/*
- * NAME
- * readv02.c
- *
+/*\
* DESCRIPTION
- * Testcase to check the error conditions of the readv(2) system call.
+ * test 1:
+ * The sum of the iov_len values overflows an ssize_t value, expect an EINVAL.
*
- * CALLS
- * readv()
+ * test 2:
+ * Buf is outside the accessible address space, expect an EFAULT.
*
- * ALGORITHM
- * Create a IO vector, and attempt to readv() various components of it.
+ * test 3:
+ * The vector count iovcnt is less than zero, expect an EINVAL.
*
- * USAGE
- * readv02
+ * test 4:
+ * The parameter passed to read is a directory, check if the errno is
+ * set to EISDIR.
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
+ * test 5:
+ * Read with an invalid file descriptor, and expect an EBADF.
*/
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <memory.h>
-#include <errno.h>
-#include "test.h"
-#include "safe_macros.h"
-
-#define K_1 1024
-#define M_1 K_1 * K_1
-#define G_1 M_1 * K_1
-
-#define NBUFS 4
-#define CHUNK 64
-#define MAX_IOVEC 16
-#define DATA_FILE "readv_data_file"
-
-char buf1[K_1], buf2[K_1], buf3[K_1];
-
-struct iovec rd_iovec[MAX_IOVEC] = {
- /* iov_base *//* iov_len */
+#include <sys/uio.h>
+#include "tst_test.h"
- /* Test case #1 */
- {buf2, -1},
- {(buf2 + CHUNK), CHUNK},
- {(buf2 + CHUNK * 2), CHUNK},
+#define K_1 1024
+#define MODES 0700
- /* Test case #2 */
- {(buf2 + CHUNK * 3), G_1},
- {(buf2 + CHUNK * 4), G_1},
- {(buf2 + CHUNK * 5), G_1},
+#define CHUNK 64
- /* Test case #3 */
- {(caddr_t) - 1, CHUNK},
- {(buf2 + CHUNK * 6), CHUNK},
- {(buf2 + CHUNK * 8), CHUNK},
+static int badfd = -1;
+static int fd[2] = {-1, -1};
+static char buf1[K_1];
+const char *TEST_DIR = "test_dir";
+const char *TEST_FILE = "test_file";
- /* Test case #4 */
- {(buf2 + CHUNK * 9), CHUNK}
+static struct iovec invalid_iovec[] = {
+ {buf1, -1},
+ {buf1 + CHUNK, CHUNK},
+ {buf1 + 2*CHUNK, CHUNK},
};
-char f_name[K_1];
-
-int fd[4];
-char *buf_list[NBUFS];
+static struct iovec large_iovec[] = {
+ {buf1, K_1},
+ {buf1 + CHUNK, K_1},
+ {buf1 + CHUNK*2, K_1},
+};
-char *TCID = "readv02";
-int TST_TOTAL = 1;
+static struct iovec efault_iovec[] = {
+ {NULL, CHUNK},
+ {buf1 + CHUNK, CHUNK},
+ {buf1 + 2*CHUNK, CHUNK},
+};
-char *bad_addr = 0;
+static struct iovec valid_iovec[] = {
+ {buf1, CHUNK},
+};
-int init_buffs(char **);
-int fill_mem(char *, int, int);
-long l_seek(int, long, int);
-char *getenv();
-void setup();
-void cleanup();
+static struct tcase {
+ int *fd;
+ void *buf;
+ int count;
+ int exp_error;
+} tcases[] = {
+ {&fd[0], invalid_iovec, 1, EINVAL},
+ {&fd[0], efault_iovec, 3, EFAULT},
+ {&fd[0], large_iovec, -1, EINVAL},
+ {&fd[1], valid_iovec, 1, EISDIR},
+ {&badfd, valid_iovec, 3, EBADF},
+};
-int main(int ac, char **av)
+static void verify_readv(unsigned int n)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- /* The following loop checks looping state if -i option given */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- /* reset tst_count in case we are looping */
- tst_count = 0;
-
-//test1:
- if (readv(fd[0], rd_iovec, 1) < 0) {
- if (errno != EINVAL) {
- tst_resm(TFAIL, "readv() set an illegal errno:"
- " expected: EINVAL, got %d", errno);
- } else {
- tst_resm(TPASS, "got EINVAL");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
-
-//test2:
- l_seek(fd[0], CHUNK * 6, 0);
- if (readv(fd[0], (rd_iovec + 6), 3) < 0) {
- if (errno != EFAULT) {
- tst_resm(TFAIL, "expected errno = EFAULT, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EFAULT");
- }
- if (memcmp((buf_list[0] + CHUNK * 6),
- (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) {
- tst_resm(TFAIL, "Error: readv() partially "
- "overlaid buf[2]");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
-
-//test3:
- if (readv(fd[1], (rd_iovec + 9), 1) < 0) {
- if (errno != EBADF) {
- tst_resm(TFAIL, "expected errno = EBADF, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EBADF");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
-
-//test4:
- l_seek(fd[0], CHUNK * 10, 0);
- if (readv(fd[0], (rd_iovec + 10), -1) < 0) {
- if (errno != EINVAL) {
- tst_resm(TFAIL, "expected errno = EINVAL, "
- "got %d", errno);
- } else {
- tst_resm(TPASS, "got EINVAL");
- }
- } else {
- tst_resm(TFAIL, "Error: readv returned a positive "
- "value");
- }
-
- }
- close(fd[0]);
- close(fd[1]);
- cleanup();
- tst_exit();
+ struct tcase *tc = &tcases[n];
+ TST_EXP_FAIL2(readv(*tc->fd, tc->buf, tc->count), tc->exp_error,
+ "readv(%d, %p, %d)", *tc->fd, tc->buf, tc->count);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void setup(void)
{
- int nbytes;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* make a temporary directory and cd to it */
- tst_tmpdir();
+ fd[0] = SAFE_OPEN(TEST_FILE, O_WRONLY | O_CREAT, 0666);
+ SAFE_WRITE(1, fd[0], buf1, CHUNK);
+ SAFE_CLOSE(fd[0]);
- buf_list[0] = buf1;
- buf_list[1] = buf2;
- buf_list[2] = buf3;
- buf_list[3] = NULL;
-
- init_buffs(buf_list);
-
- sprintf(f_name, "%s.%d", DATA_FILE, getpid());
-
- if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
- tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
- "errno = %d", f_name, errno);
- } else {
- if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) {
- tst_brkm(TBROK, cleanup, "write failed: nbytes "
- "= %d " "errno = %d", nbytes, errno);
- }
- }
+ fd[0] = SAFE_OPEN(TEST_FILE, O_RDONLY, 0666);
- SAFE_CLOSE(cleanup, fd[0]);
+ efault_iovec[0].iov_base = tst_get_bad_addr(NULL);
- if ((fd[0] = open(f_name, O_RDONLY, 0666)) < 0) {
- tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
- "errno = %d", f_name, errno);
- }
-
- fd[1] = -1; /* Invalid file descriptor */
-
- bad_addr = mmap(0, 1, PROT_NONE,
- MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
- if (bad_addr == MAP_FAILED) {
- tst_brkm(TBROK, cleanup, "mmap failed");
- }
- rd_iovec[6].iov_base = bad_addr;
+ SAFE_MKDIR(TEST_DIR, MODES);
+ fd[1] = SAFE_OPEN(TEST_DIR, O_RDONLY);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
- SAFE_UNLINK(NULL, f_name);
- tst_rmdir();
-
-}
-
-int init_buffs(char *pbufs[])
+static void cleanup(void)
{
int i;
- for (i = 0; pbufs[i] != NULL; i++) {
- switch (i) {
- case 0:
- /*FALLTHROUGH*/ case 1:
- fill_mem(pbufs[i], 0, 1);
- break;
-
- case 2:
- fill_mem(pbufs[i], 1, 0);
- break;
-
- default:
- tst_brkm(TBROK, cleanup, "Error in init_buffs()");
- }
- }
- return 0;
-}
-
-int fill_mem(char *c_ptr, int c1, int c2)
-{
- int count;
-
- for (count = 1; count <= K_1 / CHUNK; count++) {
- if (count & 0x01) { /* if odd */
- memset(c_ptr, c1, CHUNK);
- } else { /* if even */
- memset(c_ptr, c2, CHUNK);
- }
+ for (i = 0; i < 2; i++) {
+ if (fd[i] > 0)
+ SAFE_CLOSE(fd[i]);
}
- return 0;
}
-long l_seek(int fdesc, long offset, int whence)
-{
- SAFE_LSEEK(cleanup, fdesc, offset, whence);
- return 0;
-}
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcases),
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_readv,
+};
diff --git a/testcases/kernel/syscalls/readv/readv03.c b/testcases/kernel/syscalls/readv/readv03.c
deleted file mode 100644
index 8f5cddf..0000000
--- a/testcases/kernel/syscalls/readv/readv03.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) Bull S.A. 2001
- * Copyright (c) International Business Machines Corp., 2001
- * 05/2002 Ported by Jacky Malcles
- */
-
-/*\
- * [Description]
- *
- * Testcase to check EISDIR error when fd refers to a directory.
- */
-
-#include <sys/uio.h>
-#include <fcntl.h>
-#include "tst_test.h"
-
-#define K_1 1024
-#define MODES S_IRWXU
-
-static char buf1[K_1];
-
-static struct iovec rd_iovec[1] = {
- {buf1, K_1}
-};
-
-const char *TEST_DIR = "alpha";
-static int fd;
-
-static void verify_readv(void)
-{
- TST_EXP_FAIL2(readv(fd, rd_iovec, 1), EISDIR,
- "readv() got EISDIR");
-}
-
-void setup(void)
-{
- SAFE_MKDIR(TEST_DIR, MODES);
- fd = SAFE_OPEN(TEST_DIR, O_RDONLY);
-}
-
-static void cleanup(void)
-{
- if (fd > 0)
- SAFE_CLOSE(fd);
-}
-
-static struct tst_test test = {
- .needs_tmpdir = 1,
- .setup = setup,
- .cleanup = cleanup,
- .test_all = verify_readv,
-};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [LTP] [PATCH v2] syscalls/readv02: Convert to new API and merge readv03 into readv02
2021-08-15 11:02 ` [LTP] [PATCH v2] " Dai Shili
@ 2021-08-31 15:55 ` Cyril Hrubis
0 siblings, 0 replies; 5+ messages in thread
From: Cyril Hrubis @ 2021-08-31 15:55 UTC (permalink / raw)
To: ltp
Hi!
Pushed with minor changes, thanks.
- reformatted the documentation comment so that it renders nicely in
asccidoc
- got rid of the fd array, it's a bit more readable with fd_file and
fd_dir instead
- simplified setup a bit
Full diff:
diff --git a/testcases/kernel/syscalls/readv/readv02.c b/testcases/kernel/syscalls/readv/readv02.c
index 9a26e50a8..c09e69bc8 100644
--- a/testcases/kernel/syscalls/readv/readv02.c
+++ b/testcases/kernel/syscalls/readv/readv02.c
@@ -7,22 +7,15 @@
*/
/*\
- * DESCRIPTION
- * test 1:
- * The sum of the iov_len values overflows an ssize_t value, expect an EINVAL.
+ * [Description]
*
- * test 2:
- * Buf is outside the accessible address space, expect an EFAULT.
+ * Tests readv() failures:
*
- * test 3:
- * The vector count iovcnt is less than zero, expect an EINVAL.
- *
- * test 4:
- * The parameter passed to read is a directory, check if the errno is
- * set to EISDIR.
- *
- * test 5:
- * Read with an invalid file descriptor, and expect an EBADF.
+ * - EINVAL the sum of the iov_len values overflows an ssize_t value
+ * - EFAULT buffer is outside the accessible address space
+ * - EINVAL the vector count iovcnt is less than zero
+ * - EISDIR the file descriptor is a directory
+ * - EBADF the file descriptor is not valid
*/
#include <sys/uio.h>
@@ -34,7 +27,7 @@
#define CHUNK 64
static int badfd = -1;
-static int fd[2] = {-1, -1};
+static int fd_dir, fd_file;
static char buf1[K_1];
const char *TEST_DIR = "test_dir";
const char *TEST_FILE = "test_file";
@@ -67,10 +60,10 @@ static struct tcase {
int count;
int exp_error;
} tcases[] = {
- {&fd[0], invalid_iovec, 1, EINVAL},
- {&fd[0], efault_iovec, 3, EFAULT},
- {&fd[0], large_iovec, -1, EINVAL},
- {&fd[1], valid_iovec, 1, EISDIR},
+ {&fd_file, invalid_iovec, 1, EINVAL},
+ {&fd_file, efault_iovec, 3, EFAULT},
+ {&fd_file, large_iovec, -1, EINVAL},
+ {&fd_dir, valid_iovec, 1, EISDIR},
{&badfd, valid_iovec, 3, EBADF},
};
@@ -84,26 +77,23 @@ static void verify_readv(unsigned int n)
static void setup(void)
{
- fd[0] = SAFE_OPEN(TEST_FILE, O_WRONLY | O_CREAT, 0666);
- SAFE_WRITE(1, fd[0], buf1, CHUNK);
- SAFE_CLOSE(fd[0]);
+ SAFE_FILE_PRINTF(TEST_FILE, "test");
- fd[0] = SAFE_OPEN(TEST_FILE, O_RDONLY, 0666);
+ fd_file = SAFE_OPEN(TEST_FILE, O_RDONLY);
efault_iovec[0].iov_base = tst_get_bad_addr(NULL);
SAFE_MKDIR(TEST_DIR, MODES);
- fd[1] = SAFE_OPEN(TEST_DIR, O_RDONLY);
+ fd_dir = SAFE_OPEN(TEST_DIR, O_RDONLY);
}
static void cleanup(void)
{
- int i;
+ if (fd_file > 0)
+ SAFE_CLOSE(fd_file);
- for (i = 0; i < 2; i++) {
- if (fd[i] > 0)
- SAFE_CLOSE(fd[i]);
- }
+ if (fd_dir > 0)
+ SAFE_CLOSE(fd_dir);
}
static struct tst_test test = {
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-08-31 15:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-30 5:48 [LTP] [PATCH] syscalls/readv02: Convert to new API and merge readv03 into readv02 Dai Shili
2021-08-03 13:43 ` Cyril Hrubis
2021-08-04 9:37 ` [LTP] 回复: " daisl.fnst
2021-08-15 11:02 ` [LTP] [PATCH v2] " Dai Shili
2021-08-31 15:55 ` 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.