From 11cd4af6e1db2f609e257cb9983bd4c8e5971518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 30 Oct 2024 15:15:52 +0100 Subject: [PATCH] kernel/libroot: add pipe2() from POSIX.1-2024 this adds a parameter to the create_pipe syscall. Adjust strace. Change-Id: I83e9f039eb28c862458654b66c03e2e21a258822 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8513 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- headers/posix/unistd.h | 1 + headers/private/kernel/vfs.h | 2 +- headers/private/system/syscalls.h | 2 +- src/bin/debug/strace/fcntl.cpp | 5 +++++ src/bin/debug/strace/network.cpp | 4 ---- src/system/kernel/fs/vfs.cpp | 15 ++++++++++----- src/system/libroot/posix/unistd/pipe.c | 11 +++++++++-- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/headers/posix/unistd.h b/headers/posix/unistd.h index 97a3adb81a..a020c0d2d1 100644 --- a/headers/posix/unistd.h +++ b/headers/posix/unistd.h @@ -341,6 +341,7 @@ extern int fchdir(int fd); extern char *getcwd(char *buffer, size_t size); extern int pipe(int fildes[2]); +extern int pipe2(int fildes[2], int flags); extern int dup(int fd); extern int dup2(int fd1, int fd2); extern int close(int fd); diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 5f1da653a8..8dad66f244 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -206,7 +206,7 @@ status_t _user_unlink(int fd, const char *path); status_t _user_rename(int oldFD, const char *oldpath, int newFD, const char *newpath); status_t _user_create_fifo(int fd, const char *path, mode_t perms); -status_t _user_create_pipe(int *fds); +status_t _user_create_pipe(int *fds, int flags); status_t _user_access(int fd, const char *path, int mode, bool effectiveUserGroup); ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet, diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index fb33636c1a..f3dfb0d1e3 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -295,7 +295,7 @@ extern status_t _kern_unlink(int fd, const char *path); extern status_t _kern_rename(int oldDir, const char *oldpath, int newDir, const char *newpath); extern status_t _kern_create_fifo(int fd, const char *path, mode_t perms); -extern status_t _kern_create_pipe(int *fds); +extern status_t _kern_create_pipe(int *fds, int flags); extern status_t _kern_access(int fd, const char *path, int mode, bool effectiveUserGroup); extern ssize_t _kern_select(int numfds, struct fd_set *readSet, diff --git a/src/bin/debug/strace/fcntl.cpp b/src/bin/debug/strace/fcntl.cpp index 46555938f6..d7be346bd4 100644 --- a/src/bin/debug/strace/fcntl.cpp +++ b/src/bin/debug/strace/fcntl.cpp @@ -93,5 +93,10 @@ patch_fcntl() fcntl->GetParameter("argument")->SetHandler( new TypeHandlerSelector(kFcntlTypeHandlers, 1, TypeHandlerFactory::Create())); + + Syscall *createPipe = get_syscall("_kern_create_pipe"); + createPipe->ParameterAt(0)->SetOut(true); + createPipe->ParameterAt(0)->SetCount(2); + createPipe->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kOpenFlags)); } diff --git a/src/bin/debug/strace/network.cpp b/src/bin/debug/strace/network.cpp index 80022189f7..840b34c3cc 100644 --- a/src/bin/debug/strace/network.cpp +++ b/src/bin/debug/strace/network.cpp @@ -124,10 +124,6 @@ patch_network() shutdown->GetParameter("how")->SetHandler( new EnumTypeHandler(kShutdownHowMap)); - Syscall *createPipe = get_syscall("_kern_create_pipe"); - createPipe->ParameterAt(0)->SetOut(true); - createPipe->ParameterAt(0)->SetCount(2); - Syscall *socketPair = get_syscall("_kern_socketpair"); socketPair->ParameterAt(3)->SetOut(true); socketPair->ParameterAt(3)->SetCount(2); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 49113a02e3..d215e02019 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -9579,8 +9579,12 @@ _user_create_fifo(int fd, const char* userPath, mode_t perms) status_t -_user_create_pipe(int* userFDs) +_user_create_pipe(int* userFDs, int flags) { + // check acceptable flags + if ((flags & ~(O_NONBLOCK | O_CLOEXEC)) != 0) + return B_BAD_VALUE; + // rootfs should support creating FIFOs, but let's be sure if (!HAS_FS_CALL(sRoot, create_special_node)) return B_UNSUPPORTED; @@ -9606,10 +9610,11 @@ _user_create_pipe(int* userFDs) // Everything looks good so far. Open two FDs for reading respectively // writing, O_NONBLOCK to avoid blocking on open with O_RDONLY int fds[2]; - fds[0] = open_vnode(vnode, O_RDONLY | O_NONBLOCK, false); - fds[1] = open_vnode(vnode, O_WRONLY, false); - // Reset O_NONBLOCK - common_fcntl(fds[0], F_SETFL, 0, false); + fds[0] = open_vnode(vnode, O_RDONLY | O_NONBLOCK | flags, false); + fds[1] = open_vnode(vnode, O_WRONLY | flags, false); + // Reset O_NONBLOCK if requested + if ((flags & O_NONBLOCK) == 0) + common_fcntl(fds[0], F_SETFL, flags & O_NONBLOCK, false); FDCloser closer0(fds[0], false); FDCloser closer1(fds[1], false); diff --git a/src/system/libroot/posix/unistd/pipe.c b/src/system/libroot/posix/unistd/pipe.c index 1c851bf58c..222ba462ad 100644 --- a/src/system/libroot/posix/unistd/pipe.c +++ b/src/system/libroot/posix/unistd/pipe.c @@ -11,9 +11,9 @@ int -pipe(int streams[2]) +pipe2(int streams[2], int flags) { - status_t error = _kern_create_pipe(streams); + status_t error = _kern_create_pipe(streams, flags); if (error != B_OK) { __set_errno(error); return -1; @@ -21,3 +21,10 @@ pipe(int streams[2]) return 0; } + + +int +pipe(int streams[2]) +{ + return pipe2(streams, 0); +}