Message ID | 23019c9ad3a63d7026a60df8bc41934c3e74e564.1690733545.git.tanyuan@tinylab.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | tools/nolibc: add pipe(), pipe2() and their testcase | expand |
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 >
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 >
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);
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(+)