* [LTP] [PATCH v1] splices06.c: Add splice check on proc files @ 2023-08-17 0:39 Wei Gao via ltp 2023-08-30 9:45 ` [LTP] [PATCH v1] splice06.c: " Richard Palethorpe 2023-09-02 3:03 ` [LTP] [PATCH v2] splices06.c: " Wei Gao via ltp 0 siblings, 2 replies; 6+ messages in thread From: Wei Gao via ltp @ 2023-08-17 0:39 UTC (permalink / raw) To: ltp Signed-off-by: Wei Gao <wegao@suse.com> --- testcases/kernel/syscalls/splice/splice06.c | 134 ++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 testcases/kernel/syscalls/splice/splice06.c diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c new file mode 100644 index 000000000..f14fd84c5 --- /dev/null +++ b/testcases/kernel/syscalls/splice/splice06.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> + */ + +/*\ + * [Description] + * + * This test is cover splice() on proc files. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <fcntl.h> + +#include "tst_test.h" +#include "lapi/splice.h" + +#define TEST_BLOCK_SIZE 100 +#define NAME_SPACES_NUM 1024 +#define PROCFILE "/proc/sys/user/max_user_namespaces" +#define TESTFILE1 "splice_testfile_1" +#define TESTFILE2 "splice_testfile_2" + +static int fd_in, fd_out; +static int origin_name_spaces_num; +static char line[TEST_BLOCK_SIZE]; + +static void splice_file(void) +{ + int pipes[2]; + int ret; + + SAFE_PIPE(pipes); + + ret = splice(fd_in, NULL, pipes[1], NULL, TEST_BLOCK_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); + + ret = splice(pipes[0], NULL, fd_out, NULL, TEST_BLOCK_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(pipe, fd_out) failed"); + + SAFE_CLOSE(fd_in); + SAFE_CLOSE(fd_out); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); +} + +static void set_value(char file[], int num) +{ + int fd; + int len = snprintf(NULL, 0, "%d", num); + + memset(line, '\0', sizeof(line)); + sprintf(line, "%d", num); + + fd = SAFE_OPEN(file, O_RDWR | O_CREAT | O_TRUNC, 0777); + SAFE_WRITE(SAFE_WRITE_ALL, fd, line, len); + SAFE_CLOSE(fd); +} + +static int get_value(char file[]) +{ + int fd, num, ret; + + memset(line, '\0', sizeof(line)); + + fd = SAFE_OPEN(file, O_RDONLY); + SAFE_READ(0, fd, line, TEST_BLOCK_SIZE); + SAFE_CLOSE(fd); + + ret = sscanf(line, "%d", &num); + if (ret == EOF) + tst_brk(TBROK | TERRNO, "sscanf error"); + + return num; +} + +static void splice_test(void) +{ + + int name_spaces_num_setting = get_value(PROCFILE); + + fd_in = SAFE_OPEN(PROCFILE, O_RDONLY); + fd_out = SAFE_OPEN(TESTFILE2, O_WRONLY | O_CREAT | O_TRUNC, 0666); + splice_file(); + + if (name_spaces_num_setting == get_value(TESTFILE2)) + tst_res(TPASS, "Written data has been read back correctly"); + else + tst_brk(TBROK | TERRNO, "Written data has been read back failed"); + + if (get_value(PROCFILE) != NAME_SPACES_NUM) + name_spaces_num_setting = NAME_SPACES_NUM; + else + name_spaces_num_setting = NAME_SPACES_NUM + 1; + + set_value(TESTFILE1, name_spaces_num_setting); + + fd_in = SAFE_OPEN(TESTFILE1, O_RDONLY, 0777); + fd_out = SAFE_OPEN(PROCFILE, O_WRONLY, 0777); + + splice_file(); + + if (name_spaces_num_setting == get_value(PROCFILE)) + tst_res(TPASS, "Written data has been written correctly"); + else + tst_brk(TBROK | TERRNO, "Written data has been written failed"); +} + +static void setup(void) +{ + origin_name_spaces_num = get_value(PROCFILE); +} + +static void cleanup(void) +{ + set_value(PROCFILE, origin_name_spaces_num); +} + +static struct tst_test test = { + .min_kver = "5.11", + .setup = setup, + .cleanup = cleanup, + .test_all = splice_test, + .needs_tmpdir = 1, +}; -- 2.35.3 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v1] splice06.c: Add splice check on proc files 2023-08-17 0:39 [LTP] [PATCH v1] splices06.c: Add splice check on proc files Wei Gao via ltp @ 2023-08-30 9:45 ` Richard Palethorpe 2023-09-02 3:03 ` [LTP] [PATCH v2] splices06.c: " Wei Gao via ltp 1 sibling, 0 replies; 6+ messages in thread From: Richard Palethorpe @ 2023-08-30 9:45 UTC (permalink / raw) To: Wei Gao; +Cc: ltp Hello, Subject had a typo s/splices/splice/. Wei Gao via ltp <ltp@lists.linux.it> writes: > Signed-off-by: Wei Gao <wegao@suse.com> > --- > testcases/kernel/syscalls/splice/splice06.c | 134 ++++++++++++++++++++ > 1 file changed, 134 insertions(+) > create mode 100644 testcases/kernel/syscalls/splice/splice06.c > > diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c > new file mode 100644 > index 000000000..f14fd84c5 > --- /dev/null > +++ b/testcases/kernel/syscalls/splice/splice06.c > @@ -0,0 +1,134 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> > + */ > + > +/*\ > + * [Description] > + * > + * This test is cover splice() on proc files. > + * > + */ > + > +#define _GNU_SOURCE > + > +#include <stdio.h> > +#include <errno.h> > +#include <string.h> > +#include <signal.h> > +#include <sys/types.h> > +#include <fcntl.h> > + > +#include "tst_test.h" > +#include "lapi/splice.h" > + > +#define TEST_BLOCK_SIZE 100 > +#define NAME_SPACES_NUM 1024 > +#define PROCFILE "/proc/sys/user/max_user_namespaces" This file is not available on a lot of configs. I'd suggest using instead /proc/kernel/domainname which lets you read/write up to 64 bytes and is often not set. See kernel/utsname_sysctl.c We should probably also test an integer based one like /proc/sys/fs/pipe-max-size. > +#define TESTFILE1 "splice_testfile_1" > +#define TESTFILE2 "splice_testfile_2" Why do we need these files? We should be able to write to a pipe then splice it to the proc file(s). Splicing to/from a regular file is handled in other tests. Also splice from the proc file to a pipe then read the pipe. > + > +static int fd_in, fd_out; > +static int origin_name_spaces_num; > +static char line[TEST_BLOCK_SIZE]; Why are these global variables? It's not because you make sure they are closed during cleanup. > + > +static void splice_file(void) > +{ > + int pipes[2]; > + int ret; > + > + SAFE_PIPE(pipes); > + > + ret = splice(fd_in, NULL, pipes[1], NULL, TEST_BLOCK_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); > + > + ret = splice(pipes[0], NULL, fd_out, NULL, TEST_BLOCK_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(pipe, fd_out) failed"); > + > + SAFE_CLOSE(fd_in); > + SAFE_CLOSE(fd_out); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > +} > + > +static void set_value(char file[], int num) > +{ > + int fd; > + int len = snprintf(NULL, 0, "%d", num); > + > + memset(line, '\0', sizeof(line)); > + sprintf(line, "%d", num); > + > + fd = SAFE_OPEN(file, O_RDWR | O_CREAT | O_TRUNC, 0777); > + SAFE_WRITE(SAFE_WRITE_ALL, fd, line, len); > + SAFE_CLOSE(fd); We have library functions to open then read, scan or write a file. (SAFE_FILE_*). > +} > + > +static int get_value(char file[]) > +{ > + int fd, num, ret; > + > + memset(line, '\0', sizeof(line)); > + > + fd = SAFE_OPEN(file, O_RDONLY); > + SAFE_READ(0, fd, line, TEST_BLOCK_SIZE); > + SAFE_CLOSE(fd); > + > + ret = sscanf(line, "%d", &num); > + if (ret == EOF) > + tst_brk(TBROK | TERRNO, "sscanf error"); > + > + return num; > +} > + > +static void splice_test(void) > +{ > + > + int name_spaces_num_setting = get_value(PROCFILE); > + > + fd_in = SAFE_OPEN(PROCFILE, O_RDONLY); > + fd_out = SAFE_OPEN(TESTFILE2, O_WRONLY | O_CREAT | O_TRUNC, 0666); > + splice_file(); The control flow is unecessarily hard to follow here. You are opening fds in the outer scope then closing them inside splice_file(). Given that I don't think it is necessary to have TESTFILE1/2 I'll skip the rest of the function. However you need to make the control flow or data flow clearer. > + > + if (name_spaces_num_setting == get_value(TESTFILE2)) > + tst_res(TPASS, "Written data has been read back correctly"); > + else > + tst_brk(TBROK | TERRNO, "Written data has been read back failed"); > + > + if (get_value(PROCFILE) != NAME_SPACES_NUM) > + name_spaces_num_setting = NAME_SPACES_NUM; > + else > + name_spaces_num_setting = NAME_SPACES_NUM + 1; > + > + set_value(TESTFILE1, name_spaces_num_setting); > + > + fd_in = SAFE_OPEN(TESTFILE1, O_RDONLY, 0777); > + fd_out = SAFE_OPEN(PROCFILE, O_WRONLY, 0777); > + > + splice_file(); > + > + if (name_spaces_num_setting == get_value(PROCFILE)) > + tst_res(TPASS, "Written data has been written correctly"); > + else > + tst_brk(TBROK | TERRNO, "Written data has been written failed"); > +} > + > +static void setup(void) > +{ > + origin_name_spaces_num = get_value(PROCFILE); We have a save and restore feature in tst_test (tst_test.save_restore). > +} > + > +static void cleanup(void) > +{ > + set_value(PROCFILE, origin_name_spaces_num); > +} > + > +static struct tst_test test = { > + .min_kver = "5.11", > + .setup = setup, > + .cleanup = cleanup, > + .test_all = splice_test, > + .needs_tmpdir = 1, > +}; > -- > 2.35.3 -- Thank you, Richard. -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [PATCH v2] splices06.c: Add splice check on proc files 2023-08-17 0:39 [LTP] [PATCH v1] splices06.c: Add splice check on proc files Wei Gao via ltp 2023-08-30 9:45 ` [LTP] [PATCH v1] splice06.c: " Richard Palethorpe @ 2023-09-02 3:03 ` Wei Gao via ltp 2023-09-04 8:01 ` Richard Palethorpe 2023-09-04 9:45 ` [LTP] [PATCH v3] " Wei Gao via ltp 1 sibling, 2 replies; 6+ messages in thread From: Wei Gao via ltp @ 2023-09-02 3:03 UTC (permalink / raw) To: ltp Signed-off-by: Wei Gao <wegao@suse.com> --- testcases/kernel/syscalls/splice/splice06.c | 212 ++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 testcases/kernel/syscalls/splice/splice06.c diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c new file mode 100644 index 000000000..2d2403055 --- /dev/null +++ b/testcases/kernel/syscalls/splice/splice06.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> + */ + +/*\ + * [Description] + * + * This test is cover splice() on proc files. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <fcntl.h> + +#include "tst_test.h" +#include "lapi/splice.h" + +#define BUF_SIZE 100 +#define PIPE_MAX_INIT_SIZE 65536 +#define PIPE_MAX_TEST_SIZE 4096 +#define DOMAIN_INIT_NAME "LTP_INIT" +#define DOMAIN_TEST_NAME "LTP_TEST" +#define INTEGER_PROCFILE "/proc/sys/fs/pipe-max-size" +#define STRING_PROCFILE "/proc/sys/kernel/domainname" + +static int splice_read_num(char file[]) +{ + int pipes[2]; + int fd_in; + int ret; + int num; + char buf[BUF_SIZE]; + + memset(buf, '\0', sizeof(buf)); + fd_in = SAFE_OPEN(file, O_RDONLY); + SAFE_PIPE(pipes); + + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); + + SAFE_READ(0, pipes[0], buf, BUF_SIZE); + + /* Replace LF to '\0' otherwise tst_parse_int will report error */ + buf[strlen(buf)-1] = '\0'; + + if (tst_parse_int(buf, &num, 0, INT_MAX)) + tst_brk(TBROK, "Invalid buffer num %s", buf); + + SAFE_CLOSE(fd_in); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); + + return num; +} + +static char *splice_read_str(char file[], char *dest) +{ + int pipes[2]; + int fd_in; + int ret; + + fd_in = SAFE_OPEN(file, O_RDONLY); + SAFE_PIPE(pipes); + + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); + + SAFE_READ(0, pipes[0], dest, BUF_SIZE); + + SAFE_CLOSE(fd_in); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); + + return dest; +} + + +static void splice_write_num(char file[], int num) +{ + int pipes[2]; + int fd_out; + int ret; + char buf[BUF_SIZE]; + + memset(buf, '\0', sizeof(buf)); + + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); + SAFE_PIPE(pipes); + sprintf(buf, "%d", num); + + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buf, strlen(buf)); + + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice write failed"); + + SAFE_CLOSE(fd_out); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); +} + +static void splice_write_str(char file[], char *dest) +{ + int pipes[2]; + int fd_out; + int ret; + + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); + SAFE_PIPE(pipes); + + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], dest, strlen(dest)); + + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice write failed"); + + SAFE_CLOSE(fd_out); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); +} + +static void file_write_num(char file[], int num) +{ + SAFE_FILE_PRINTF(file, "%d", num); +} + +static void file_write_str(char file[], char *dest) +{ + SAFE_FILE_PRINTF(file, "%s", dest); +} + +static int file_read_num(char file[]) +{ + int num; + + SAFE_FILE_SCANF(file, "%d", &num); + + return num; +} + +static char *file_read_str(char file[], char *dest) +{ + SAFE_FILE_SCANF(file, "%s", dest); + return dest; +} + +static void splice_test(void) +{ + + char buf_file[BUF_SIZE]; + char buf_splice[BUF_SIZE]; + + if (file_read_num(INTEGER_PROCFILE) == splice_read_num(INTEGER_PROCFILE)) + tst_res(TPASS, "Read num through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Read num through splice failed"); + + splice_write_num(INTEGER_PROCFILE, PIPE_MAX_TEST_SIZE); + + if (file_read_num(INTEGER_PROCFILE) == PIPE_MAX_TEST_SIZE) + tst_res(TPASS, "Write num through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Write num through splice failed"); + + memset(buf_file, '\0', sizeof(buf_file)); + memset(buf_splice, '\0', sizeof(buf_splice)); + + file_read_str(STRING_PROCFILE, buf_file); + splice_read_str(STRING_PROCFILE, buf_splice); + + if (!strncmp(buf_file, buf_splice, strlen(buf_file))) + tst_res(TPASS, "Read string through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Read string through splice failed"); + + memset(buf_file, '\0', sizeof(buf_file)); + + splice_write_str(STRING_PROCFILE, DOMAIN_TEST_NAME); + file_read_str(STRING_PROCFILE, buf_file); + + if (!strncmp(buf_file, DOMAIN_TEST_NAME, strlen(buf_file))) + tst_res(TPASS, "Write string through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Write string through splice failed"); +} + +static void setup(void) +{ + file_write_str(STRING_PROCFILE, DOMAIN_INIT_NAME); + file_write_num(STRING_PROCFILE, PIPE_MAX_INIT_SIZE); +} + +static struct tst_test test = { + .min_kver = "5.11", + .setup = setup, + .test_all = splice_test, + .needs_tmpdir = 1, + .save_restore = (const struct tst_path_val[]) { + {INTEGER_PROCFILE, NULL, TST_SR_TCONF}, + {STRING_PROCFILE, NULL, TST_SR_TCONF}, + {} + }, +}; -- 2.35.3 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2] splices06.c: Add splice check on proc files 2023-09-02 3:03 ` [LTP] [PATCH v2] splices06.c: " Wei Gao via ltp @ 2023-09-04 8:01 ` Richard Palethorpe 2023-09-04 9:45 ` [LTP] [PATCH v3] " Wei Gao via ltp 1 sibling, 0 replies; 6+ messages in thread From: Richard Palethorpe @ 2023-09-04 8:01 UTC (permalink / raw) To: Wei Gao; +Cc: ltp Hello, Thanks this is much easier to understand, but see comments below. Wei Gao via ltp <ltp@lists.linux.it> writes: > Signed-off-by: Wei Gao <wegao@suse.com> > --- > testcases/kernel/syscalls/splice/splice06.c | 212 ++++++++++++++++++++ > 1 file changed, 212 insertions(+) > create mode 100644 testcases/kernel/syscalls/splice/splice06.c > > diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c > new file mode 100644 > index 000000000..2d2403055 > --- /dev/null > +++ b/testcases/kernel/syscalls/splice/splice06.c > @@ -0,0 +1,212 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> > + */ > + > +/*\ > + * [Description] > + * > + * This test is cover splice() on proc files. > + * > + */ > + > +#define _GNU_SOURCE > + > +#include <stdio.h> > +#include <errno.h> > +#include <string.h> > +#include <signal.h> > +#include <sys/types.h> > +#include <fcntl.h> > + > +#include "tst_test.h" > +#include "lapi/splice.h" > + > +#define BUF_SIZE 100 > +#define PIPE_MAX_INIT_SIZE 65536 > +#define PIPE_MAX_TEST_SIZE 4096 > +#define DOMAIN_INIT_NAME "LTP_INIT" > +#define DOMAIN_TEST_NAME "LTP_TEST" > +#define INTEGER_PROCFILE "/proc/sys/fs/pipe-max-size" > +#define STRING_PROCFILE "/proc/sys/kernel/domainname" > + > +static int splice_read_num(char file[]) Why are you passing a char array instead of a pointer? I see this so rarely that I'm not sure if it is the same as a pointer or if the memory will be copied. I think it should be char *const. > +{ > + int pipes[2]; > + int fd_in; > + int ret; > + int num; > + char buf[BUF_SIZE]; > + > + memset(buf, '\0', sizeof(buf)); > + fd_in = SAFE_OPEN(file, O_RDONLY); > + SAFE_PIPE(pipes); > + > + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); As a general rule you shouldn't write into the whole buffer from an untrusted source if it is expected to be a null terminated string. So it should be (BUF_SIZE - 1). > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); > + > + SAFE_READ(0, pipes[0], buf, BUF_SIZE); > + > + /* Replace LF to '\0' otherwise tst_parse_int will report error */ > + buf[strlen(buf)-1] = '\0'; What if there is no LF, is that a bug? I don't know if the file is guaranteed to contain LF at the end. In any case I think it would be better to search for the first non numeric character and replace it with \0. If it's not there print a fail or warning, because maybe we didn't get the whole file. > + > + if (tst_parse_int(buf, &num, 0, INT_MAX)) > + tst_brk(TBROK, "Invalid buffer num %s", buf); > + > + SAFE_CLOSE(fd_in); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > + > + return num; > +} > + > +static char *splice_read_str(char file[], char *dest) Again an array of char and dest could be const. > +{ > + int pipes[2]; > + int fd_in; > + int ret; > + > + fd_in = SAFE_OPEN(file, O_RDONLY); > + SAFE_PIPE(pipes); > + > + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); > + > + SAFE_READ(0, pipes[0], dest, BUF_SIZE); > + > + SAFE_CLOSE(fd_in); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > + > + return dest; > +} > + > + > +static void splice_write_num(char file[], int num) and here and for the rest. > +{ > + int pipes[2]; > + int fd_out; > + int ret; > + char buf[BUF_SIZE]; > + > + memset(buf, '\0', sizeof(buf)); > + > + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); > + SAFE_PIPE(pipes); > + sprintf(buf, "%d", num); > + > + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buf, strlen(buf)); > + > + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice write failed"); > + > + SAFE_CLOSE(fd_out); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > +} > + > +static void splice_write_str(char file[], char *dest) > +{ > + int pipes[2]; > + int fd_out; > + int ret; > + > + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); > + SAFE_PIPE(pipes); > + > + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], dest, strlen(dest)); > + > + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice write failed"); > + > + SAFE_CLOSE(fd_out); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > +} > + > +static void file_write_num(char file[], int num) > +{ > + SAFE_FILE_PRINTF(file, "%d", num); > +} > + > +static void file_write_str(char file[], char *dest) > +{ > + SAFE_FILE_PRINTF(file, "%s", dest); > +} > + > +static int file_read_num(char file[]) > +{ > + int num; > + > + SAFE_FILE_SCANF(file, "%d", &num); > + > + return num; > +} > + > +static char *file_read_str(char file[], char *dest) > +{ > + SAFE_FILE_SCANF(file, "%s", dest); > + return dest; > +} > + > +static void splice_test(void) > +{ > + > + char buf_file[BUF_SIZE]; > + char buf_splice[BUF_SIZE]; > + > + if (file_read_num(INTEGER_PROCFILE) == splice_read_num(INTEGER_PROCFILE)) > + tst_res(TPASS, "Read num through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Read num through splice failed"); > + > + splice_write_num(INTEGER_PROCFILE, PIPE_MAX_TEST_SIZE); > + > + if (file_read_num(INTEGER_PROCFILE) == PIPE_MAX_TEST_SIZE) > + tst_res(TPASS, "Write num through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Write num through splice failed"); > + > + memset(buf_file, '\0', sizeof(buf_file)); > + memset(buf_splice, '\0', sizeof(buf_splice)); > + > + file_read_str(STRING_PROCFILE, buf_file); > + splice_read_str(STRING_PROCFILE, buf_splice); > + > + if (!strncmp(buf_file, buf_splice, strlen(buf_file))) > + tst_res(TPASS, "Read string through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Read string through splice failed"); > + > + memset(buf_file, '\0', sizeof(buf_file)); > + > + splice_write_str(STRING_PROCFILE, DOMAIN_TEST_NAME); > + file_read_str(STRING_PROCFILE, buf_file); > + > + if (!strncmp(buf_file, DOMAIN_TEST_NAME, strlen(buf_file))) > + tst_res(TPASS, "Write string through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Write string through splice failed"); > +} > + > +static void setup(void) > +{ > + file_write_str(STRING_PROCFILE, DOMAIN_INIT_NAME); > + file_write_num(STRING_PROCFILE, PIPE_MAX_INIT_SIZE); > +} > + > +static struct tst_test test = { > + .min_kver = "5.11", > + .setup = setup, > + .test_all = splice_test, > + .needs_tmpdir = 1, > + .save_restore = (const struct tst_path_val[]) { > + {INTEGER_PROCFILE, NULL, TST_SR_TCONF}, > + {STRING_PROCFILE, NULL, TST_SR_TCONF}, > + {} > + }, > +}; > -- > 2.35.3 -- Thank you, Richard. -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [PATCH v3] splices06.c: Add splice check on proc files 2023-09-02 3:03 ` [LTP] [PATCH v2] splices06.c: " Wei Gao via ltp 2023-09-04 8:01 ` Richard Palethorpe @ 2023-09-04 9:45 ` Wei Gao via ltp 2023-09-29 10:27 ` Richard Palethorpe 1 sibling, 1 reply; 6+ messages in thread From: Wei Gao via ltp @ 2023-09-04 9:45 UTC (permalink / raw) To: ltp Signed-off-by: Wei Gao <wegao@suse.com> --- testcases/kernel/syscalls/splice/splice06.c | 227 ++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 testcases/kernel/syscalls/splice/splice06.c diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c new file mode 100644 index 000000000..3139d16db --- /dev/null +++ b/testcases/kernel/syscalls/splice/splice06.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> + */ + +/*\ + * [Description] + * + * This test is cover splice() on proc files. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <fcntl.h> +#include <ctype.h> + +#include "tst_test.h" +#include "lapi/splice.h" + +#define BUF_SIZE 100 +#define PIPE_MAX_INIT_SIZE 65536 +#define PIPE_MAX_TEST_SIZE 4096 +#define DOMAIN_INIT_NAME "LTP_INIT" +#define DOMAIN_TEST_NAME "LTP_TEST" +#define INTEGER_PROCFILE "/proc/sys/fs/pipe-max-size" +#define STRING_PROCFILE "/proc/sys/kernel/domainname" + +static void format_str(char *str) +{ + int i; + + for (i = 0; i < BUF_SIZE ; i++) { + if (!isdigit(str[i])) { + str[i] = '\0'; + break; + } + } + if (i == BUF_SIZE) + tst_brk(TBROK, "can not find nonnumeric character from input string"); +} + +static int splice_read_num(const char *file) +{ + int pipes[2]; + int fd_in; + int ret; + int num; + char buf[BUF_SIZE]; + + memset(buf, '\0', sizeof(buf)); + fd_in = SAFE_OPEN(file, O_RDONLY); + SAFE_PIPE(pipes); + + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE - 1, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); + + SAFE_READ(0, pipes[0], buf, BUF_SIZE); + + /* Search for the first nonnumeric character and replace it with \0 */ + format_str(buf); + + if (tst_parse_int(buf, &num, 0, INT_MAX)) + tst_brk(TBROK, "Invalid buffer num %s", buf); + + SAFE_CLOSE(fd_in); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); + + return num; +} + +static char *splice_read_str(const char *file, char *dest) +{ + int pipes[2]; + int fd_in; + int ret; + + fd_in = SAFE_OPEN(file, O_RDONLY); + SAFE_PIPE(pipes); + + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); + + SAFE_READ(0, pipes[0], dest, BUF_SIZE); + + SAFE_CLOSE(fd_in); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); + + return dest; +} + + +static void splice_write_num(const char *file, int num) +{ + int pipes[2]; + int fd_out; + int ret; + char buf[BUF_SIZE]; + + memset(buf, '\0', sizeof(buf)); + + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); + SAFE_PIPE(pipes); + sprintf(buf, "%d", num); + + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buf, strlen(buf)); + + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice write failed"); + + SAFE_CLOSE(fd_out); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); +} + +static void splice_write_str(const char *file, char *dest) +{ + int pipes[2]; + int fd_out; + int ret; + + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); + SAFE_PIPE(pipes); + + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], dest, strlen(dest)); + + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); + if (ret < 0) + tst_brk(TBROK | TERRNO, "splice write failed"); + + SAFE_CLOSE(fd_out); + SAFE_CLOSE(pipes[0]); + SAFE_CLOSE(pipes[1]); +} + +static void file_write_num(const char *file, int num) +{ + SAFE_FILE_PRINTF(file, "%d", num); +} + +static void file_write_str(const char *file, char *dest) +{ + SAFE_FILE_PRINTF(file, "%s", dest); +} + +static int file_read_num(const char *file) +{ + int num; + + SAFE_FILE_SCANF(file, "%d", &num); + + return num; +} + +static char *file_read_str(const char *file, char *dest) +{ + SAFE_FILE_SCANF(file, "%s", dest); + return dest; +} + +static void splice_test(void) +{ + + char buf_file[BUF_SIZE]; + char buf_splice[BUF_SIZE]; + + if (file_read_num(INTEGER_PROCFILE) == splice_read_num(INTEGER_PROCFILE)) + tst_res(TPASS, "Read num through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Read num through splice failed"); + + splice_write_num(INTEGER_PROCFILE, PIPE_MAX_TEST_SIZE); + + if (file_read_num(INTEGER_PROCFILE) == PIPE_MAX_TEST_SIZE) + tst_res(TPASS, "Write num through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Write num through splice failed"); + + memset(buf_file, '\0', sizeof(buf_file)); + memset(buf_splice, '\0', sizeof(buf_splice)); + + file_read_str(STRING_PROCFILE, buf_file); + splice_read_str(STRING_PROCFILE, buf_splice); + + if (!strncmp(buf_file, buf_splice, strlen(buf_file))) + tst_res(TPASS, "Read string through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Read string through splice failed"); + + memset(buf_file, '\0', sizeof(buf_file)); + + splice_write_str(STRING_PROCFILE, DOMAIN_TEST_NAME); + file_read_str(STRING_PROCFILE, buf_file); + + if (!strncmp(buf_file, DOMAIN_TEST_NAME, strlen(buf_file))) + tst_res(TPASS, "Write string through splice correctly"); + else + tst_brk(TBROK | TERRNO, "Write string through splice failed"); +} + +static void setup(void) +{ + file_write_str(STRING_PROCFILE, DOMAIN_INIT_NAME); + file_write_num(STRING_PROCFILE, PIPE_MAX_INIT_SIZE); +} + +static struct tst_test test = { + .min_kver = "5.11", + .setup = setup, + .test_all = splice_test, + .needs_tmpdir = 1, + .save_restore = (const struct tst_path_val[]) { + {INTEGER_PROCFILE, NULL, TST_SR_TCONF}, + {STRING_PROCFILE, NULL, TST_SR_TCONF}, + {} + }, +}; -- 2.35.3 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v3] splices06.c: Add splice check on proc files 2023-09-04 9:45 ` [LTP] [PATCH v3] " Wei Gao via ltp @ 2023-09-29 10:27 ` Richard Palethorpe 0 siblings, 0 replies; 6+ messages in thread From: Richard Palethorpe @ 2023-09-29 10:27 UTC (permalink / raw) To: Wei Gao; +Cc: ltp nit: still has typo in subject, but that can be fixed at merge. Reviewed-by: Richard Palethorpe <rpalethorpe@suse.com> Wei Gao via ltp <ltp@lists.linux.it> writes: > Signed-off-by: Wei Gao <wegao@suse.com> > --- > testcases/kernel/syscalls/splice/splice06.c | 227 ++++++++++++++++++++ > 1 file changed, 227 insertions(+) > create mode 100644 testcases/kernel/syscalls/splice/splice06.c > > diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c > new file mode 100644 > index 000000000..3139d16db > --- /dev/null > +++ b/testcases/kernel/syscalls/splice/splice06.c > @@ -0,0 +1,227 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2023 SUSE LLC <wegao@suse.com> > + */ > + > +/*\ > + * [Description] > + * > + * This test is cover splice() on proc files. > + * > + */ > + > +#define _GNU_SOURCE > + > +#include <stdio.h> > +#include <errno.h> > +#include <string.h> > +#include <signal.h> > +#include <sys/types.h> > +#include <fcntl.h> > +#include <ctype.h> > + > +#include "tst_test.h" > +#include "lapi/splice.h" > + > +#define BUF_SIZE 100 > +#define PIPE_MAX_INIT_SIZE 65536 > +#define PIPE_MAX_TEST_SIZE 4096 > +#define DOMAIN_INIT_NAME "LTP_INIT" > +#define DOMAIN_TEST_NAME "LTP_TEST" > +#define INTEGER_PROCFILE "/proc/sys/fs/pipe-max-size" > +#define STRING_PROCFILE "/proc/sys/kernel/domainname" > + > +static void format_str(char *str) > +{ > + int i; > + > + for (i = 0; i < BUF_SIZE ; i++) { > + if (!isdigit(str[i])) { > + str[i] = '\0'; > + break; > + } > + } > + if (i == BUF_SIZE) > + tst_brk(TBROK, "can not find nonnumeric character from input string"); > +} > + > +static int splice_read_num(const char *file) > +{ > + int pipes[2]; > + int fd_in; > + int ret; > + int num; > + char buf[BUF_SIZE]; > + > + memset(buf, '\0', sizeof(buf)); > + fd_in = SAFE_OPEN(file, O_RDONLY); > + SAFE_PIPE(pipes); > + > + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE - 1, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); > + > + SAFE_READ(0, pipes[0], buf, BUF_SIZE); > + > + /* Search for the first nonnumeric character and replace it with \0 */ > + format_str(buf); > + > + if (tst_parse_int(buf, &num, 0, INT_MAX)) > + tst_brk(TBROK, "Invalid buffer num %s", buf); > + > + SAFE_CLOSE(fd_in); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > + > + return num; > +} > + > +static char *splice_read_str(const char *file, char *dest) > +{ > + int pipes[2]; > + int fd_in; > + int ret; > + > + fd_in = SAFE_OPEN(file, O_RDONLY); > + SAFE_PIPE(pipes); > + > + ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed"); > + > + SAFE_READ(0, pipes[0], dest, BUF_SIZE); > + > + SAFE_CLOSE(fd_in); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > + > + return dest; > +} > + > + > +static void splice_write_num(const char *file, int num) > +{ > + int pipes[2]; > + int fd_out; > + int ret; > + char buf[BUF_SIZE]; > + > + memset(buf, '\0', sizeof(buf)); > + > + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); > + SAFE_PIPE(pipes); > + sprintf(buf, "%d", num); > + > + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buf, strlen(buf)); > + > + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice write failed"); > + > + SAFE_CLOSE(fd_out); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > +} > + > +static void splice_write_str(const char *file, char *dest) > +{ > + int pipes[2]; > + int fd_out; > + int ret; > + > + fd_out = SAFE_OPEN(file, O_WRONLY, 0777); > + SAFE_PIPE(pipes); > + > + SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], dest, strlen(dest)); > + > + ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0); > + if (ret < 0) > + tst_brk(TBROK | TERRNO, "splice write failed"); > + > + SAFE_CLOSE(fd_out); > + SAFE_CLOSE(pipes[0]); > + SAFE_CLOSE(pipes[1]); > +} > + > +static void file_write_num(const char *file, int num) > +{ > + SAFE_FILE_PRINTF(file, "%d", num); > +} > + > +static void file_write_str(const char *file, char *dest) > +{ > + SAFE_FILE_PRINTF(file, "%s", dest); > +} > + > +static int file_read_num(const char *file) > +{ > + int num; > + > + SAFE_FILE_SCANF(file, "%d", &num); > + > + return num; > +} > + > +static char *file_read_str(const char *file, char *dest) > +{ > + SAFE_FILE_SCANF(file, "%s", dest); > + return dest; > +} > + > +static void splice_test(void) > +{ > + > + char buf_file[BUF_SIZE]; > + char buf_splice[BUF_SIZE]; > + > + if (file_read_num(INTEGER_PROCFILE) == splice_read_num(INTEGER_PROCFILE)) > + tst_res(TPASS, "Read num through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Read num through splice failed"); > + > + splice_write_num(INTEGER_PROCFILE, PIPE_MAX_TEST_SIZE); > + > + if (file_read_num(INTEGER_PROCFILE) == PIPE_MAX_TEST_SIZE) > + tst_res(TPASS, "Write num through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Write num through splice failed"); > + > + memset(buf_file, '\0', sizeof(buf_file)); > + memset(buf_splice, '\0', sizeof(buf_splice)); > + > + file_read_str(STRING_PROCFILE, buf_file); > + splice_read_str(STRING_PROCFILE, buf_splice); > + > + if (!strncmp(buf_file, buf_splice, strlen(buf_file))) > + tst_res(TPASS, "Read string through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Read string through splice failed"); > + > + memset(buf_file, '\0', sizeof(buf_file)); > + > + splice_write_str(STRING_PROCFILE, DOMAIN_TEST_NAME); > + file_read_str(STRING_PROCFILE, buf_file); > + > + if (!strncmp(buf_file, DOMAIN_TEST_NAME, strlen(buf_file))) > + tst_res(TPASS, "Write string through splice correctly"); > + else > + tst_brk(TBROK | TERRNO, "Write string through splice failed"); > +} > + > +static void setup(void) > +{ > + file_write_str(STRING_PROCFILE, DOMAIN_INIT_NAME); > + file_write_num(STRING_PROCFILE, PIPE_MAX_INIT_SIZE); > +} > + > +static struct tst_test test = { > + .min_kver = "5.11", > + .setup = setup, > + .test_all = splice_test, > + .needs_tmpdir = 1, > + .save_restore = (const struct tst_path_val[]) { > + {INTEGER_PROCFILE, NULL, TST_SR_TCONF}, > + {STRING_PROCFILE, NULL, TST_SR_TCONF}, > + {} > + }, > +}; > -- > 2.35.3 -- Thank you, Richard. -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-09-29 10:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-08-17 0:39 [LTP] [PATCH v1] splices06.c: Add splice check on proc files Wei Gao via ltp 2023-08-30 9:45 ` [LTP] [PATCH v1] splice06.c: " Richard Palethorpe 2023-09-02 3:03 ` [LTP] [PATCH v2] splices06.c: " Wei Gao via ltp 2023-09-04 8:01 ` Richard Palethorpe 2023-09-04 9:45 ` [LTP] [PATCH v3] " Wei Gao via ltp 2023-09-29 10:27 ` Richard Palethorpe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox