diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -908,6 +908,33 @@ free(kif, M_TEMP); break; + case F_DUP_OPATH: + tmp = arg; + error = fget_unlocked(td, fd, &cap_no_rights, &fp); + if (error != 0) + break; + if (fp->f_type == DTYPE_VNODE) { + error = falloc_noinstall(td, &fp2); + if (error == 0) { + int indx; + + fp2->f_vnode = fp->f_vnode; + vref(fp2->f_vnode); + finit(fp2, fp->f_flag & (FMASK | FKQALLOWED), + DTYPE_VNODE, NULL, &path_fileops); + error = finstall_refed(td, fp2, &indx, tmp, + NULL); + if (error == 0) + td->td_retval[0] = indx; + else + falloc_abort(td, fp2); + } + } else { + error = EINVAL; + } + fdrop(fp, td); + break; + default: error = EINVAL; break; diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -269,6 +269,7 @@ #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_DUP_OPATH 23 /* Dup fd to O_PATH-like */ /* Seals (F_ADD_SEALS, F_GET_SEALS). */ #define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */