git: 8732746cbeff - stable/14 - Add kern_openatfp(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 31 Jan 2024 00:46:03 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=8732746cbeffb3831ba144ac5999b200d63332a0
commit 8732746cbeffb3831ba144ac5999b200d63332a0
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-01-20 20:34:46 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-01-30 20:24:42 +0000
Add kern_openatfp(9)
(cherry picked from commit c662306e19ce60d0f5e5e32a22ddcd5c79a90849)
---
sys/kern/vfs_syscalls.c | 39 ++++++++++++++++++++++++++++++++++++---
sys/sys/syscallsubr.h | 2 ++
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 41bf2ff1d3c7..0915751785f4 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1112,9 +1112,14 @@ sys_openat(struct thread *td, struct openat_args *uap)
uap->mode));
}
-int
-kern_openat(struct thread *td, int dirfd, const char *path,
- enum uio_seg pathseg, int flags, int mode)
+/*
+ * If fpp != NULL, opened file is not installed into the file
+ * descriptor table, instead it is returned in *fpp. This is
+ * incompatible with fdopen(), in which case we return EINVAL.
+ */
+static int
+openatfp(struct thread *td, int dirfd, const char *path,
+ enum uio_seg pathseg, int flags, int mode, struct file **fpp)
{
struct proc *p;
struct filedesc *fdp;
@@ -1188,6 +1193,7 @@ kern_openat(struct thread *td, int dirfd, const char *path,
if ((nd.ni_resflags & NIRES_STRICTREL) == 0 &&
(error == ENODEV || error == ENXIO) &&
td->td_dupfd >= 0) {
+ MPASS(fpp == NULL);
error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
&indx);
if (error == 0)
@@ -1229,6 +1235,13 @@ kern_openat(struct thread *td, int dirfd, const char *path,
goto bad;
}
success:
+ if (fpp != NULL) {
+ MPASS(error == 0);
+ NDFREE_IOCTLCAPS(&nd);
+ *fpp = fp;
+ return (0);
+ }
+
/*
* If we haven't already installed the FD (for dupfdopen), do so now.
*/
@@ -1258,6 +1271,26 @@ bad:
return (error);
}
+int
+kern_openat(struct thread *td, int dirfd, const char *path,
+ enum uio_seg pathseg, int flags, int mode)
+{
+ return (openatfp(td, dirfd, path, pathseg, flags, mode, NULL));
+}
+
+int
+kern_openatfp(struct thread *td, int dirfd, const char *path,
+ enum uio_seg pathseg, int flags, int mode, struct file **fpp)
+{
+ int error, old_dupfd;
+
+ old_dupfd = td->td_dupfd;
+ td->td_dupfd = -1;
+ error = openatfp(td, dirfd, path, pathseg, flags, mode, fpp);
+ td->td_dupfd = old_dupfd;
+ return (error);
+}
+
#ifdef COMPAT_43
/*
* Create a file.
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 294ff6ef00b9..15e05985e75f 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -253,6 +253,8 @@ int kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot,
int oflags, int fd, long pos);
int kern_openat(struct thread *td, int dirfd, const char *path,
enum uio_seg pathseg, int flags, int mode);
+int kern_openatfp(struct thread *td, int dirfd, const char *path,
+ enum uio_seg pathseg, int flags, int mode, struct file **fpp);
int kern_pathconf(struct thread *td, const char *path,
enum uio_seg pathseg, int name, u_long flags, long *valuep);
int kern_pipe(struct thread *td, int fildes[2], int flags,