git: ca39124ff3bb - stable/13 - Add kern_openatfp(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 31 Jan 2024 01:02:06 UTC
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ca39124ff3bbebc34a62f36b4a231976e2de9f10 commit ca39124ff3bbebc34a62f36b4a231976e2de9f10 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:33 +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 494bae687406..7dcdaa66adb8 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1103,9 +1103,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; @@ -1179,6 +1184,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) @@ -1220,6 +1226,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. */ @@ -1249,6 +1262,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 02e5b1a4c077..77c16d8fffc0 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -230,6 +230,8 @@ int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, long *ploff); 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,