Index: lib/libc/sys/fcntl.2 =================================================================== --- lib/libc/sys/fcntl.2 +++ lib/libc/sys/fcntl.2 @@ -28,7 +28,7 @@ .\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94 .\" $FreeBSD$ .\" -.Dd December 7, 2021 +.Dd December 20, 2021 .Dt FCNTL 2 .Os .Sh NAME @@ -207,6 +207,29 @@ member of the passed structure must be initialized with the sizeof of .Vt struct kinfo_file , to allow for the interface versioning and evolution. +The +.Va kf_path +contains a path to the same object that is referenced by file +.Fa fd . +The path returned is not guaranteed to match the path used to open. +.Vt The file descriptor, or it could be that the path cannot be recovered, in which case the +.Va kf_path +field contains an empty string. +.It Dv F_GETPATH +Place a pathname corresponding to +.Fa fd +in the buffer pointed by +.Fa arg . +.Fa arg +buffer size must be at least +.Fa PATH_MAX +bytes and must be a +.Fa char * . +.Va F_GETPATH +is a wrapper around +.Va F_KINFO +.Vt and thus fetches significantly more data than only path. +.Vt It should be noted that we provide it for compability with NetBSD and macOs. .El .Pp The flags for the Index: lib/libc/sys/fcntl.c =================================================================== --- lib/libc/sys/fcntl.c +++ lib/libc/sys/fcntl.c @@ -38,8 +38,10 @@ #include #include +#include #include #include +#include #include "libc_private.h" #pragma weak fcntl @@ -50,6 +52,19 @@ long arg; va_start(args, cmd); + + if (cmd == F_GETPATH) { + struct kinfo_file kif = {.kf_structsize = KINFO_FILE_SIZE}; + char *buf = va_arg(args, char *); + va_end(args); + + int error = fcntl(fd, F_KINFO, &kif); + if (error == 0) + strcpy(buf, kif.kf_path); + + return (error); + } + arg = va_arg(args, long); va_end(args); Index: sys/sys/fcntl.h =================================================================== --- sys/sys/fcntl.h +++ sys/sys/fcntl.h @@ -271,6 +271,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_GETPATH 23 /* Return the path for this fd */ /* Seals (F_ADD_SEALS, F_GET_SEALS). */ #define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */