Add kern_openatfp(9)

Reviewed by:	markj, pjd
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D43529
This commit is contained in:
Konstantin Belousov 2024-01-20 22:34:46 +02:00
parent 3d59b93b20
commit c662306e19
2 changed files with 38 additions and 3 deletions

View File

@ -1110,9 +1110,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;
@ -1186,6 +1191,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)
@ -1227,6 +1233,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.
*/
@ -1256,6 +1269,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.

View File

@ -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,