* [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase
@ 2023-07-31 5:50 Yuan Tan
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 5:50 UTC (permalink / raw)
To: w, thomas; +Cc: falcon, linux-kernel, linux-kselftest, Yuan Tan
Hi, Willy, Thomas,
Thanks to your advice and I really learned a lot from it.
V2 now uses pipe2() to wrap pipe(), and fixes the strcmp issue in test
case.
Best regards,
Yuan Tan
Yuan Tan (2):
tools/nolibc: add pipe() and pipe2() support
selftests/nolibc: add testcase for pipe
tools/include/nolibc/sys.h | 24 ++++++++++++++
tools/testing/selftests/nolibc/nolibc-test.c | 35 ++++++++++++++++++++
2 files changed, 59 insertions(+)
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support
2023-07-31 5:50 [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Yuan Tan
@ 2023-07-31 5:50 ` Yuan Tan
2023-07-31 6:07 ` Thomas Weißschuh
2023-07-31 6:13 ` Thomas Weißschuh
2023-07-31 5:51 ` [PATCH v2 2/2] selftests/nolibc: add testcase for pipe Yuan Tan
2023-07-31 6:13 ` [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Thomas Weißschuh
2 siblings, 2 replies; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 5:50 UTC (permalink / raw)
To: w, thomas; +Cc: falcon, linux-kernel, linux-kselftest, Yuan Tan
According to manual page [1], posix spec [2] and source code like
arch/mips/kernel/syscall.c, for historic reasons, the sys_pipe() syscall
on some architectures has an unusual calling convention. It returns
results in two registers which means there is no need for it to do
verify the validity of a userspace pointer argument. Historically that
used to be expensive in Linux. These days the performance advantage is
negligible.
Nolibc doesn't support the unusual calling convention above, luckily
Linux provides a generic sys_pipe2() with an additional flags argument
from 2.6.27. If flags is 0, then pipe2() is the same as pipe(). So here
we use sys_pipe2() to implement the pipe().
pipe2() is also provided to allow users to use flags argument on demand.
[1]: https://man7.org/linux/man-pages/man2/pipe.2.html
[2]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html
Suggested-by: Zhangjin Wu <falcon@tinylab.org>
Link: https://lore.kernel.org/all/20230729100401.GA4577@1wt.eu/
Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
---
tools/include/nolibc/sys.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 8bfe7db20b80..9fec09c22dbe 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -752,6 +752,30 @@ int open(const char *path, int flags, ...)
}
+/*
+ * int pipe2(int pipefd[2], int flags);
+ * int pipe(int pipefd[2]);
+ */
+
+static __attribute__((unused))
+int sys_pipe2(int pipefd[2], int flags)
+{
+ return my_syscall2(__NR_pipe, pipefd, flags);
+}
+
+static __attribute__((unused))
+int pipe2(int pipefd[2], int flags)
+{
+ return __sysret(sys_pipe2(pipefd, flags));
+}
+
+static __attribute__((unused))
+int pipe(int pipefd[2])
+{
+ pipe2(pipefd, 0);
+}
+
+
/*
* int prctl(int option, unsigned long arg2, unsigned long arg3,
* unsigned long arg4, unsigned long arg5);
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 5:50 [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Yuan Tan
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
@ 2023-07-31 5:51 ` Yuan Tan
2023-07-31 6:10 ` Thomas Weißschuh
2023-07-31 6:13 ` [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Thomas Weißschuh
2 siblings, 1 reply; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 5:51 UTC (permalink / raw)
To: w, thomas; +Cc: falcon, linux-kernel, linux-kselftest, Yuan Tan
Add a testcase of pipe that child process sends message to parent
process.
Here we use memcmp() to avoid the output buffer issue.
Suggested-by: Thomas Weißschuh <thomas@t-8ch.de>
Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/all/c5de2d13-3752-4e1b-90d9-f58cca99c702@t-8ch.de/
Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
---
tools/testing/selftests/nolibc/nolibc-test.c | 35 ++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 03b1d30f5507..2653ab8d5124 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -767,6 +767,41 @@ int test_mmap_munmap(void)
return ret;
}
+int test_pipe(void)
+{
+ const char *const msg = "hello, nolibc";
+ int pipefd[2];
+ char buf[32];
+ pid_t pid;
+ ssize_t len;
+
+ if (pipe(pipefd) == -1)
+ return 1;
+
+ pid = fork();
+
+ switch (pid) {
+ case -1:
+ return 1;
+
+ case 0:
+ close(pipefd[0]);
+ write(pipefd[1], msg, strlen(msg));
+ close(pipefd[1]);
+ exit(EXIT_SUCCESS);
+
+ default:
+ close(pipefd[1]);
+ len = read(pipefd[0], buf, sizeof(buf));
+ close(pipefd[0]);
+ waitpid(pid, NULL, 0);
+
+ if (len != strlen(msg))
+ return 1;
+ return !!memcmp(buf, msg, len);
+ }
+}
+
/* Run syscall tests between IDs <min> and <max>.
* Return 0 on success, non-zero on failure.
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
@ 2023-07-31 6:07 ` Thomas Weißschuh
2023-07-31 6:13 ` Thomas Weißschuh
1 sibling, 0 replies; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 6:07 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
On 2023-07-31 13:50:45+0800, Yuan Tan wrote:
> According to manual page [1], posix spec [2] and source code like
> arch/mips/kernel/syscall.c, for historic reasons, the sys_pipe() syscall
> on some architectures has an unusual calling convention. It returns
> results in two registers which means there is no need for it to do
> verify the validity of a userspace pointer argument. Historically that
> used to be expensive in Linux. These days the performance advantage is
> negligible.
>
> Nolibc doesn't support the unusual calling convention above, luckily
> Linux provides a generic sys_pipe2() with an additional flags argument
> from 2.6.27. If flags is 0, then pipe2() is the same as pipe(). So here
> we use sys_pipe2() to implement the pipe().
>
> pipe2() is also provided to allow users to use flags argument on demand.
>
> [1]: https://man7.org/linux/man-pages/man2/pipe.2.html
> [2]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html
>
> Suggested-by: Zhangjin Wu <falcon@tinylab.org>
> Link: https://lore.kernel.org/all/20230729100401.GA4577@1wt.eu/
> Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
> ---
> tools/include/nolibc/sys.h | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index 8bfe7db20b80..9fec09c22dbe 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -752,6 +752,30 @@ int open(const char *path, int flags, ...)
> }
>
>
> +/*
> + * int pipe2(int pipefd[2], int flags);
> + * int pipe(int pipefd[2]);
> + */
> +
> +static __attribute__((unused))
> +int sys_pipe2(int pipefd[2], int flags)
> +{
> + return my_syscall2(__NR_pipe, pipefd, flags);
> +}
Should be __NR_pipe2.
> +static __attribute__((unused))
> +int pipe2(int pipefd[2], int flags)
> +{
> + return __sysret(sys_pipe2(pipefd, flags));
> +}
> +
> +static __attribute__((unused))
> +int pipe(int pipefd[2])
> +{
> + pipe2(pipefd, 0);
> +}
> +
> +
> /*
> * int prctl(int option, unsigned long arg2, unsigned long arg3,
> * unsigned long arg4, unsigned long arg5);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 5:51 ` [PATCH v2 2/2] selftests/nolibc: add testcase for pipe Yuan Tan
@ 2023-07-31 6:10 ` Thomas Weißschuh
2023-07-31 12:35 ` Yuan Tan
0 siblings, 1 reply; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 6:10 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> Add a testcase of pipe that child process sends message to parent
> process.
Thinking about it some more:
What's the advantage of going via a child process?
The pipe should work the same within the same process.
> Here we use memcmp() to avoid the output buffer issue.
This sentence is meaningless without the background from v1.
You can drop it.
> Suggested-by: Thomas Weißschuh <thomas@t-8ch.de>
> Suggested-by: Willy Tarreau <w@1wt.eu>
> Link: https://lore.kernel.org/all/c5de2d13-3752-4e1b-90d9-f58cca99c702@t-8ch.de/
> Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
> ---
> tools/testing/selftests/nolibc/nolibc-test.c | 35 ++++++++++++++++++++
> 1 file changed, 35 insertions(+)
>
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index 03b1d30f5507..2653ab8d5124 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -767,6 +767,41 @@ int test_mmap_munmap(void)
> return ret;
> }
>
> +int test_pipe(void)
Should be static and actually get called :-)
> +{
> + const char *const msg = "hello, nolibc";
> + int pipefd[2];
> + char buf[32];
> + pid_t pid;
> + ssize_t len;
> +
> + if (pipe(pipefd) == -1)
> + return 1;
> +
> + pid = fork();
> +
> + switch (pid) {
> + case -1:
> + return 1;
> +
> + case 0:
> + close(pipefd[0]);
> + write(pipefd[1], msg, strlen(msg));
> + close(pipefd[1]);
> + exit(EXIT_SUCCESS);
> +
> + default:
> + close(pipefd[1]);
> + len = read(pipefd[0], buf, sizeof(buf));
> + close(pipefd[0]);
> + waitpid(pid, NULL, 0);
> +
> + if (len != strlen(msg))
> + return 1;
> + return !!memcmp(buf, msg, len);
> + }
> +}
> +
>
> /* Run syscall tests between IDs <min> and <max>.
> * Return 0 on success, non-zero on failure.
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase
2023-07-31 5:50 [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Yuan Tan
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
2023-07-31 5:51 ` [PATCH v2 2/2] selftests/nolibc: add testcase for pipe Yuan Tan
@ 2023-07-31 6:13 ` Thomas Weißschuh
2023-07-31 11:08 ` Yuan Tan
2 siblings, 1 reply; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 6:13 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
Hi Yuan!
On 2023-07-31 13:50:31+0800, Yuan Tan wrote:
> Thanks to your advice and I really learned a lot from it.
>
> V2 now uses pipe2() to wrap pipe(), and fixes the strcmp issue in test
> case.
Thanks!
I have some more comments for the patches.
For new revisions you should also link to the old revision.
> Best regards,
> Yuan Tan
>
> Yuan Tan (2):
> tools/nolibc: add pipe() and pipe2() support
> selftests/nolibc: add testcase for pipe
>
> tools/include/nolibc/sys.h | 24 ++++++++++++++
> tools/testing/selftests/nolibc/nolibc-test.c | 35 ++++++++++++++++++++
> 2 files changed, 59 insertions(+)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
2023-07-31 6:07 ` Thomas Weißschuh
@ 2023-07-31 6:13 ` Thomas Weißschuh
1 sibling, 0 replies; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 6:13 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
On 2023-07-31 13:50:45+0800, Yuan Tan wrote:
> [..]
> +static __attribute__((unused))
> +int pipe(int pipefd[2])
> +{
> + pipe2(pipefd, 0);
This is missing a "return".
> +}
> +
> +
> /*
> * int prctl(int option, unsigned long arg2, unsigned long arg3,
> * unsigned long arg4, unsigned long arg5);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase
2023-07-31 6:13 ` [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Thomas Weißschuh
@ 2023-07-31 11:08 ` Yuan Tan
0 siblings, 0 replies; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 11:08 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: w, tanyuan, falcon, linux-kernel, linux-kselftest
Hi Thomas,
On Mon, 2023-07-31 at 08:13 +0200, Thomas Weißschuh wrote:
> Hi Yuan!
>
> On 2023-07-31 13:50:31+0800, Yuan Tan wrote:
> > Thanks to your advice and I really learned a lot from it.
> >
> > V2 now uses pipe2() to wrap pipe(), and fixes the strcmp issue in
> > test
> > case.
>
> Thanks!
>
> I have some more comments for the patches.
>
> For new revisions you should also link to the old revision.
>
I sincerely appreciate your valuable advice. As a newcomer, I will
certainly take note of it next time. :)
> > Best regards,
> > Yuan Tan
> >
> > Yuan Tan (2):
> > tools/nolibc: add pipe() and pipe2() support
> > selftests/nolibc: add testcase for pipe
> >
> > tools/include/nolibc/sys.h | 24 ++++++++++++++
> > tools/testing/selftests/nolibc/nolibc-test.c | 35
> > ++++++++++++++++++++
> > 2 files changed, 59 insertions(+)
> >
> > --
> > 2.34.1
> >
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 6:10 ` Thomas Weißschuh
@ 2023-07-31 12:35 ` Yuan Tan
2023-07-31 15:41 ` Thomas Weißschuh
0 siblings, 1 reply; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 12:35 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: falcon, linux-kernel, linux-kselftest, w
Hi Thomas,
On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > Add a testcase of pipe that child process sends message to parent
> > process.
>
> Thinking about it some more:
>
> What's the advantage of going via a child process?
> The pipe should work the same within the same process.
>
The pipe is commonly used for process communication, and I think as a
test case it is supposed to cover the most common scenarios.
> > Here we use memcmp() to avoid the output buffer issue.
>
> This sentence is meaningless without the background from v1.
> You can drop it.
>
Got it.
> > Suggested-by: Thomas Weißschuh <thomas@t-8ch.de>
> > Suggested-by: Willy Tarreau <w@1wt.eu>
> > Link: https://lore.kernel.org/all/c5de2d13-3752-4e1b-90d9-f58cca99c702@t-8ch.de/
> > Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
> > ---
> > tools/testing/selftests/nolibc/nolibc-test.c | 35 ++++++++++++++++++++
> > 1 file changed, 35 insertions(+)
> >
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index 03b1d30f5507..2653ab8d5124 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -767,6 +767,41 @@ int test_mmap_munmap(void)
> > return ret;
> > }
> >
> > +int test_pipe(void)
>
> Should be static and actually get called :-)
>
> > +{
> > + const char *const msg = "hello, nolibc";
> > + int pipefd[2];
> > + char buf[32];
> > + pid_t pid;
> > + ssize_t len;
> > +
> > + if (pipe(pipefd) == -1)
> > + return 1;
> > +
> > + pid = fork();
> > +
> > + switch (pid) {
> > + case -1:
> > + return 1;
> > +
> > + case 0:
> > + close(pipefd[0]);
> > + write(pipefd[1], msg, strlen(msg));
> > + close(pipefd[1]);
> > + exit(EXIT_SUCCESS);
> > +
> > + default:
> > + close(pipefd[1]);
> > + len = read(pipefd[0], buf, sizeof(buf));
> > + close(pipefd[0]);
> > + waitpid(pid, NULL, 0);
> > +
> > + if (len != strlen(msg))
> > + return 1;
> > + return !!memcmp(buf, msg, len);
> > + }
> > +}
> > +
> >
> > /* Run syscall tests between IDs <min> and <max>.
> > * Return 0 on success, non-zero on failure.
> > --
> > 2.34.1
> >
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 12:35 ` Yuan Tan
@ 2023-07-31 15:41 ` Thomas Weißschuh
2023-07-31 18:01 ` Yuan Tan
0 siblings, 1 reply; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 15:41 UTC (permalink / raw)
To: Yuan Tan; +Cc: falcon, linux-kernel, linux-kselftest, w
On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > Add a testcase of pipe that child process sends message to parent
> > > process.
> >
> > Thinking about it some more:
> >
> > What's the advantage of going via a child process?
> > The pipe should work the same within the same process.
> >
>
> The pipe is commonly used for process communication, and I think as a
> test case it is supposed to cover the most common scenarios.
The testcase is supposed to cover the code of nolibc.
It should be the *minimal* amount of code to be reasonable sure that the
code in nolibc does the correct thing.
If pipe() returns a value that behaves like a pipe I see no reason to
doubt it will also survive fork().
Validating that would mean testing the kernel and not nolibc.
For the kernel there are different testsuites.
Less code means less work for everyone involved, now and in the future.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 15:41 ` Thomas Weißschuh
@ 2023-07-31 18:01 ` Yuan Tan
2023-07-31 18:28 ` Thomas Weißschuh
0 siblings, 1 reply; 16+ messages in thread
From: Yuan Tan @ 2023-07-31 18:01 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: w, falcon, linux-kernel, linux-kselftest, tanyuan
Hi Thomas,
On Mon, 2023-07-31 at 17:41 +0200, Thomas Weißschuh wrote:
> On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> > On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > > Add a testcase of pipe that child process sends message to
> > > > parent
> > > > process.
> > >
> > > Thinking about it some more:
> > >
> > > What's the advantage of going via a child process?
> > > The pipe should work the same within the same process.
> > >
> >
> > The pipe is commonly used for process communication, and I think as
> > a
> > test case it is supposed to cover the most common scenarios.
>
> The testcase is supposed to cover the code of nolibc.
> It should be the *minimal* amount of code to be reasonable sure that
> the
> code in nolibc does the correct thing.
> If pipe() returns a value that behaves like a pipe I see no reason to
> doubt it will also survive fork().
>
> Validating that would mean testing the kernel and not nolibc.
> For the kernel there are different testsuites.
>
> Less code means less work for everyone involved, now and in the
> future.
>
It's a good point and I never thought about this aspect.
I wonder whether the code below is enough?
static int test_pipe(void)
{
int pipefd[2];
if (pipe(pipefd) == -1)
return 1;
close(pipefd[0]);
close(pipefd[1]);
return 0;
}
And I forgot to add this line:
CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
I will add it in next patch.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 18:01 ` Yuan Tan
@ 2023-07-31 18:28 ` Thomas Weißschuh
2023-08-01 6:51 ` Yuan Tan
0 siblings, 1 reply; 16+ messages in thread
From: Thomas Weißschuh @ 2023-07-31 18:28 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
On 2023-08-01 02:01:36+0800, Yuan Tan wrote:
> Hi Thomas,
> On Mon, 2023-07-31 at 17:41 +0200, Thomas Weißschuh wrote:
> > On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> > > On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > > > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > > > Add a testcase of pipe that child process sends message to
> > > > > parent
> > > > > process.
> > > >
> > > > Thinking about it some more:
> > > >
> > > > What's the advantage of going via a child process?
> > > > The pipe should work the same within the same process.
> > > >
> > >
> > > The pipe is commonly used for process communication, and I think as
> > > a
> > > test case it is supposed to cover the most common scenarios.
> >
> > The testcase is supposed to cover the code of nolibc.
> > It should be the *minimal* amount of code to be reasonable sure that
> > the
> > code in nolibc does the correct thing.
> > If pipe() returns a value that behaves like a pipe I see no reason to
> > doubt it will also survive fork().
> >
> > Validating that would mean testing the kernel and not nolibc.
> > For the kernel there are different testsuites.
> >
> > Less code means less work for everyone involved, now and in the
> > future.
> >
>
> It's a good point and I never thought about this aspect.
>
> I wonder whether the code below is enough?
>
> static int test_pipe(void)
> {
> int pipefd[2];
>
> if (pipe(pipefd) == -1)
> return 1;
>
> close(pipefd[0]);
> close(pipefd[1]);
>
> return 0;
> }
That is very barebones.
If accidentally a wrong syscall number was used and the used syscall
would not take any arguments this test would still succeed.
Keeping the write-read-cycle from the previous revision would test that
nicely. Essentially the same code as before but without the fork().
>
> And I forgot to add this line:
>
> CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
>
> I will add it in next patch.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-07-31 18:28 ` Thomas Weißschuh
@ 2023-08-01 6:51 ` Yuan Tan
2023-08-01 7:20 ` Thomas Weißschuh
0 siblings, 1 reply; 16+ messages in thread
From: Yuan Tan @ 2023-08-01 6:51 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: w, falcon, linux-kernel, linux-kselftest, tanyuan
Hi Thomas,
On Mon, 2023-07-31 at 20:28 +0200, Thomas Weißschuh wrote:
> On 2023-08-01 02:01:36+0800, Yuan Tan wrote:
> > Hi Thomas,
> > On Mon, 2023-07-31 at 17:41 +0200, Thomas Weißschuh wrote:
> > > On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> > > > On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > > > > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > > > > Add a testcase of pipe that child process sends message to
> > > > > > parent
> > > > > > process.
> > > > >
> > > > > Thinking about it some more:
> > > > >
> > > > > What's the advantage of going via a child process?
> > > > > The pipe should work the same within the same process.
> > > > >
> > > >
> > > > The pipe is commonly used for process communication, and I
> > > > think as
> > > > a
> > > > test case it is supposed to cover the most common scenarios.
> > >
> > > The testcase is supposed to cover the code of nolibc.
> > > It should be the *minimal* amount of code to be reasonable sure
> > > that
> > > the
> > > code in nolibc does the correct thing.
> > > If pipe() returns a value that behaves like a pipe I see no
> > > reason to
> > > doubt it will also survive fork().
> > >
> > > Validating that would mean testing the kernel and not nolibc.
> > > For the kernel there are different testsuites.
> > >
> > > Less code means less work for everyone involved, now and in the
> > > future.
> > >
> >
> > It's a good point and I never thought about this aspect.
> >
> > I wonder whether the code below is enough?
> >
> > static int test_pipe(void)
> > {
> > int pipefd[2];
> >
> > if (pipe(pipefd) == -1)
> > return 1;
> >
> > close(pipefd[0]);
> > close(pipefd[1]);
> >
> > return 0;
> > }
>
> That is very barebones.
>
> If accidentally a wrong syscall number was used and the used syscall
> would not take any arguments this test would still succeed.
>
> Keeping the write-read-cycle from the previous revision would test
> that
> nicely. Essentially the same code as before but without the fork().
>
> >
> > And I forgot to add this line:
> >
> > CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
> >
> > I will add it in next patch.
> >
>
In the situation you described, that is indeed the case.
Would this be fine?
static int test_pipe(void)
{
const char *const msg = "hello, nolibc";
int pipefd[2];
char buf[32];
ssize_t len;
if (pipe(pipefd) == -1)
return 1;
write(pipefd[1], msg, strlen(msg));
close(pipefd[1]);
len = read(pipefd[0], buf, sizeof(buf));
close(pipefd[0]);
if (len != strlen(msg))
return 1;
return !!memcmp(buf, msg, len);
}
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-08-01 6:51 ` Yuan Tan
@ 2023-08-01 7:20 ` Thomas Weißschuh
2023-08-01 12:23 ` Yuan Tan
0 siblings, 1 reply; 16+ messages in thread
From: Thomas Weißschuh @ 2023-08-01 7:20 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
On 2023-08-01 14:51:40+0800, Yuan Tan wrote:
> Hi Thomas,
>
> On Mon, 2023-07-31 at 20:28 +0200, Thomas Weißschuh wrote:
> > On 2023-08-01 02:01:36+0800, Yuan Tan wrote:
> > > Hi Thomas,
> > > On Mon, 2023-07-31 at 17:41 +0200, Thomas Weißschuh wrote:
> > > > On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> > > > > On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > > > > > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > > > > > Add a testcase of pipe that child process sends message to
> > > > > > > parent
> > > > > > > process.
> > > > > >
> > > > > > Thinking about it some more:
> > > > > >
> > > > > > What's the advantage of going via a child process?
> > > > > > The pipe should work the same within the same process.
> > > > > >
> > > > >
> > > > > The pipe is commonly used for process communication, and I
> > > > > think as
> > > > > a
> > > > > test case it is supposed to cover the most common scenarios.
> > > >
> > > > The testcase is supposed to cover the code of nolibc.
> > > > It should be the *minimal* amount of code to be reasonable sure
> > > > that
> > > > the
> > > > code in nolibc does the correct thing.
> > > > If pipe() returns a value that behaves like a pipe I see no
> > > > reason to
> > > > doubt it will also survive fork().
> > > >
> > > > Validating that would mean testing the kernel and not nolibc.
> > > > For the kernel there are different testsuites.
> > > >
> > > > Less code means less work for everyone involved, now and in the
> > > > future.
> > > >
> > >
> > > It's a good point and I never thought about this aspect.
> > >
> > > I wonder whether the code below is enough?
> > >
> > > static int test_pipe(void)
> > > {
> > > int pipefd[2];
> > >
> > > if (pipe(pipefd) == -1)
> > > return 1;
> > >
> > > close(pipefd[0]);
> > > close(pipefd[1]);
> > >
> > > return 0;
> > > }
> >
> > That is very barebones.
> >
> > If accidentally a wrong syscall number was used and the used syscall
> > would not take any arguments this test would still succeed.
> >
> > Keeping the write-read-cycle from the previous revision would test
> > that
> > nicely. Essentially the same code as before but without the fork().
> >
> > >
> > > And I forgot to add this line:
> > >
> > > CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
> > >
> > > I will add it in next patch.
> > >
> >
>
> In the situation you described, that is indeed the case.
>
> Would this be fine?
>
> static int test_pipe(void)
> {
> const char *const msg = "hello, nolibc";
> int pipefd[2];
> char buf[32];
> ssize_t len;
>
> if (pipe(pipefd) == -1)
> return 1;
>
> write(pipefd[1], msg, strlen(msg));
> close(pipefd[1]);
> len = read(pipefd[0], buf, sizeof(buf));
> close(pipefd[0]);
>
> if (len != strlen(msg))
> return 1;
>
> return !!memcmp(buf, msg, len);
> }
Looks good!
The return value of write() could also be validated but given we
validate the return value from read() it shouldn't make a difference.
(Also the manual manipulation of "buf" is gone that necessitated the
check in v1 of the series)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-08-01 7:20 ` Thomas Weißschuh
@ 2023-08-01 12:23 ` Yuan Tan
2023-08-01 14:46 ` Thomas Weißschuh
0 siblings, 1 reply; 16+ messages in thread
From: Yuan Tan @ 2023-08-01 12:23 UTC (permalink / raw)
To: Thomas Weißschuh; +Cc: w, falcon, linux-kernel, linux-kselftest, tanyuan
Hi Thomas,
On Tue, 2023-08-01 at 09:20 +0200, Thomas Weißschuh wrote:
> On 2023-08-01 14:51:40+0800, Yuan Tan wrote:
> > Hi Thomas,
> >
> > On Mon, 2023-07-31 at 20:28 +0200, Thomas Weißschuh wrote:
> > > On 2023-08-01 02:01:36+0800, Yuan Tan wrote:
> > > > Hi Thomas,
> > > > On Mon, 2023-07-31 at 17:41 +0200, Thomas Weißschuh wrote:
> > > > > On 2023-07-31 20:35:28+0800, Yuan Tan wrote:
> > > > > > On Mon, 2023-07-31 at 08:10 +0200, Thomas Weißschuh wrote:
> > > > > > > On 2023-07-31 13:51:00+0800, Yuan Tan wrote:
> > > > > > > > Add a testcase of pipe that child process sends message
> > > > > > > > to
> > > > > > > > parent
> > > > > > > > process.
> > > > > > >
> > > > > > > Thinking about it some more:
> > > > > > >
> > > > > > > What's the advantage of going via a child process?
> > > > > > > The pipe should work the same within the same process.
> > > > > > >
> > > > > >
> > > > > > The pipe is commonly used for process communication, and I
> > > > > > think as
> > > > > > a
> > > > > > test case it is supposed to cover the most common
> > > > > > scenarios.
> > > > >
> > > > > The testcase is supposed to cover the code of nolibc.
> > > > > It should be the *minimal* amount of code to be reasonable
> > > > > sure
> > > > > that
> > > > > the
> > > > > code in nolibc does the correct thing.
> > > > > If pipe() returns a value that behaves like a pipe I see no
> > > > > reason to
> > > > > doubt it will also survive fork().
> > > > >
> > > > > Validating that would mean testing the kernel and not nolibc.
> > > > > For the kernel there are different testsuites.
> > > > >
> > > > > Less code means less work for everyone involved, now and in
> > > > > the
> > > > > future.
> > > > >
> > > >
> > > > It's a good point and I never thought about this aspect.
> > > >
> > > > I wonder whether the code below is enough?
> > > >
> > > > static int test_pipe(void)
> > > > {
> > > > int pipefd[2];
> > > >
> > > > if (pipe(pipefd) == -1)
> > > > return 1;
> > > >
> > > > close(pipefd[0]);
> > > > close(pipefd[1]);
> > > >
> > > > return 0;
> > > > }
> > >
> > > That is very barebones.
> > >
> > > If accidentally a wrong syscall number was used and the used
> > > syscall
> > > would not take any arguments this test would still succeed.
> > >
> > > Keeping the write-read-cycle from the previous revision would
> > > test
> > > that
> > > nicely. Essentially the same code as before but without the
> > > fork().
> > >
> > > >
> > > > And I forgot to add this line:
> > > >
> > > > CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
> > > >
> > > > I will add it in next patch.
> > > >
> > >
> >
> > In the situation you described, that is indeed the case.
> >
> > Would this be fine?
> >
> > static int test_pipe(void)
> > {
> > const char *const msg = "hello, nolibc";
> > int pipefd[2];
> > char buf[32];
> > ssize_t len;
> >
> > if (pipe(pipefd) == -1)
> > return 1;
> >
> > write(pipefd[1], msg, strlen(msg));
> > close(pipefd[1]);
> > len = read(pipefd[0], buf, sizeof(buf));
> > close(pipefd[0]);
> >
> > if (len != strlen(msg))
> > return 1;
> >
> > return !!memcmp(buf, msg, len);
> > }
>
> Looks good!
>
> The return value of write() could also be validated but given we
> validate the return value from read() it shouldn't make a difference.
>
> (Also the manual manipulation of "buf" is gone that necessitated the
> check in v1 of the series)
>
I am sorry that I didn't catch your last sentence.
Did you mean this piece of code does not need any further modifications
right?
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] selftests/nolibc: add testcase for pipe
2023-08-01 12:23 ` Yuan Tan
@ 2023-08-01 14:46 ` Thomas Weißschuh
0 siblings, 0 replies; 16+ messages in thread
From: Thomas Weißschuh @ 2023-08-01 14:46 UTC (permalink / raw)
To: Yuan Tan; +Cc: w, falcon, linux-kernel, linux-kselftest
Aug 1, 2023 14:23:22 Yuan Tan <tanyuan@tinylab.org>:
>>> Would this be fine?
>>>
>>> static int test_pipe(void)
>>> {
>>> const char *const msg = "hello, nolibc";
>>> int pipefd[2];
>>> char buf[32];
>>> ssize_t len;
>>>
>>> if (pipe(pipefd) == -1)
>>> return 1;
>>>
>>> write(pipefd[1], msg, strlen(msg));
>>> close(pipefd[1]);
>>> len = read(pipefd[0], buf, sizeof(buf));
>>> close(pipefd[0]);
>>>
>>> if (len != strlen(msg))
>>> return 1;
>>>
>>> return !!memcmp(buf, msg, len);
>>> }
>>
>> Looks good!
>>
>> The return value of write() could also be validated but given we
>> validate the return value from read() it shouldn't make a difference.
>>
>> (Also the manual manipulation of "buf" is gone that necessitated the
>> check in v1 of the series)
>>
>
> I am sorry that I didn't catch your last sentence.
>
> Did you mean this piece of code does not need any further modifications
> right?
Yes, for me this is great!
Sorry for being unclear.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-08-01 14:46 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-31 5:50 [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Yuan Tan
2023-07-31 5:50 ` [PATCH v2 1/2] tools/nolibc: add pipe() and pipe2() support Yuan Tan
2023-07-31 6:07 ` Thomas Weißschuh
2023-07-31 6:13 ` Thomas Weißschuh
2023-07-31 5:51 ` [PATCH v2 2/2] selftests/nolibc: add testcase for pipe Yuan Tan
2023-07-31 6:10 ` Thomas Weißschuh
2023-07-31 12:35 ` Yuan Tan
2023-07-31 15:41 ` Thomas Weißschuh
2023-07-31 18:01 ` Yuan Tan
2023-07-31 18:28 ` Thomas Weißschuh
2023-08-01 6:51 ` Yuan Tan
2023-08-01 7:20 ` Thomas Weißschuh
2023-08-01 12:23 ` Yuan Tan
2023-08-01 14:46 ` Thomas Weißschuh
2023-07-31 6:13 ` [PATCH v2 0/2] tools/nolibc: add pipe(), pipe2() and their testcase Thomas Weißschuh
2023-07-31 11:08 ` Yuan Tan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox