Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Jul 2020 18:59:35 +0200
From:      Mateusz Guzik <mjguzik@gmail.com>
To:        Yuri <yuri@rawbw.com>
Cc:        Freebsd hackers list <freebsd-hackers@freebsd.org>
Subject:   Re: Is it possible to determine the open file path based on the file descriptor?
Message-ID:  <CAGudoHHE7UcNsT5hB8zRwhjABBCP2-rtFcuHE=dhmPwvf=6XgA@mail.gmail.com>
In-Reply-To: <CAGudoHEjFvt4nijEUj0FwN0CTYmuxuqvSbiMefTeMvrXeuEkJg@mail.gmail.com>
References:  <21b0280d-c290-f27f-98a9-0c2242380718@rawbw.com> <CAGudoHEjFvt4nijEUj0FwN0CTYmuxuqvSbiMefTeMvrXeuEkJg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 7/8/20, Mateusz Guzik <mjguzik@gmail.com> wrote:
> On 7/8/20, Yuri <yuri@rawbw.com> wrote:
>> Hi Hackers,
>>
>>
>> One of the ports (sysutils/watchman) attempts to find the path of the
>> file based on the file descriptor assuming that this descriptor
>> represents an open file.
>>
>>
>> Is this possible?
>>
>>
>
> Yes and no. procstat -f can report that, but not always. The crux is
> that the namecache is optional -- no name may be present and then we
> don't have good means to find it. There is a side corner case where
> you can have *more* than one name and then the kernel has no idea
> which was used to reach the file for given fd.
>
> I think the namecache should start getting new names in all cases and
> that's perhaps something to change for 13.
>
> Even for the working case the interface used by procstat is a bad pick.
>
> That said, I can add a fcntl which will translate the fd into a full
> path if the name can be found, but I don't know how useful it can be
> with this program given the stipulation above.
>

Now that I wrote that e-mail I remembered I already implemented this,
here is a forward version against head:
https://people.freebsd.org/~mjg/F_GETPATH.diff

#include <fcntl.h>

#define MAXPATHLEN 1024
#define F_GETPATH 22

int
main(int argc, char **argv)
{
	char buf[MAXPATHLEN];
	int fd;

	if (argc != 2)
		return (1);

	fd = open(argv[1], O_RDONLY);
	if (fd == -1)
		err(1, "open");

	if (fcntl(fd, F_GETPATH, buf) == -1)
		err(1, "fcntl");
	printf("[%s]\n", buf);
}

I can't be arsed to find all the proper headers, but you get the idea.
If this makes the program work well enough I can commit and merge to
stable/12.

-- 
Mateusz Guzik <mjguzik gmail.com>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGudoHHE7UcNsT5hB8zRwhjABBCP2-rtFcuHE=dhmPwvf=6XgA>