commit ea7423238b85e5227d58b46b6496746d85a672e8 Author: Mateusz Guzik Date: Sun Dec 19 13:14:37 2021 +0000 fd: add F_GETPATH diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d5d22ecfc522..a9da8f83efef 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -480,6 +480,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) struct proc *p; struct vnode *vp; struct mount *mp; + char *retbuf, *freebuf; struct kinfo_file *kif; int error, flg, kif_sz, seals, tmp; uint64_t bsize; @@ -891,6 +892,37 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) free(kif, M_TEMP); break; + case F_GETPATH: + /* + * Translate a vnode to a path. + * + * The process is unreliable in the following ways: + * - if the target has more than one name, it is not specified + * which one will be returned (most notably it may differ + * from the name used to open it to obtain given fd) + * - there may be no names added to begin with (none were added + * to the name cache or they got evicted), in which case the + * routine may fail + * + * See top level comment in kern/vfs_cache.c for more details. + */ + error = fget_unlocked(fdp, fd, &cap_no_rights, &fp); + if (__predict_false(error != 0)) + break; + if (__predict_false(fp->f_type != DTYPE_VNODE)) { + fdrop(fp, td); + error = EBADF; + break; + } + vp = fp->f_vnode; + error = vn_fullpath(vp, &retbuf, &freebuf); + fdrop(fp, td); + if (__predict_false(error != 0)) + break; + error = copyout(retbuf, (void *)arg, strlen(retbuf) + 1); + free(freebuf, M_TEMP); + break; + default: error = EINVAL; break; diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 491b0172a1e6..5264be2d9852 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -271,6 +271,7 @@ typedef __pid_t pid_t; #define F_GET_SEALS 20 #define F_ISUNIONSTACK 21 /* Kludge for libc, don't use it. */ #define F_KINFO 22 /* Return kinfo_file for this fd */ +#define F_GETPATH 23 /* Resolve the fd to a path */ /* Seals (F_ADD_SEALS, F_GET_SEALS). */ #define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */