Why fs.File doesn't have a method to generate full path

Hi I’m new to zig and stumbled to see that an object of fs.File doesn’t have a method to generate fullpath. Is there a way to get it ?

For fs.Dir type I’m using dir.realpathAlloc(allocator, ".") (dir is fs.Dir type) to get the dir full path but can’t find anything for fs.File

1 Like

Hi, The closest thing to it that I know, is to use std.fs.cwd().realpathAlloc() I think. Idk if It’s the thing you were looking for.

Hi

I am guessing that you want to pass std.fs.File to a function and be able to get its directory path?

My understanding is that to get the std.fs.File in the first place, you need to know the directory it is in. Therefore you should know it’s corresponding std.fs.Dir. And therefore the directory of the file. AFAIK You cannot easily work back from a file to a directory.

To get round this problem I would create a stuct which includes the std.fd.File and std.fs.Dir and pass that instead. Every file would then have its corresponding std.fs.Dir.

As I understand it

std.fs.File has an INode number to access the file. Unfortunately this does not include it’s file path.

see
https://www.bluematador.com/blog/what-is-an-inode-and-what-are-they-used-for

What are inodes used for?

Data is stored on your disk in the form of fixed-size blocks. If you save a file that exceeds a standard block, your computer will find the next available segment on which to store the rest of your file. Over time, that can get super confusing.

That’s where inodes come in. While they don’t contain any of the file’s actual data, it stores the file’s metadata, including all the storage blocks on which the file’s data can be found.

Information contained in an inode:

File size
Device on which the file is stored 
User and group IDs associated with the file
Permissions needed to access the file
Creation, read, and write timestamps
Location of the data (though not the filepath)

Inodes are also independent of filenames. That means you can copy a single file, rename it, and still have it point to the same inode as the original.

Hope that helps

1 Like

The function you’re looking for is std.os.getFdPath. To call it for a File, you’d pass it file.handle; to call it for a Dir, you’d pass it dir.fd. Calling it with the result of std.fs.cwd() should be done with great care (on POSIX systems, std.fs.cwd() does not return a real fd, see here).

However, take note of its documentation:

/// This function is very host-specific and is not universally supported by all hosts.
/// For example, while it generally works on Linux, macOS, FreeBSD or Windows, it is
/// unsupported on WASI.
///
/// Calling this function is usually a bug.

Related issue that pertains to getFdPath and realpath generally:

1 Like

Thank you for taking the time to correct me.

But how did you know that? I looked for well over 1/2 hour. Didn’t even think to check out Std.os. Is this just an experience thing? Or am I missing something?

I’ve worked a lot on std.fs and related APIs, so I was already aware of it. It’s also what std.posix.realpath/std.fs.Dir.realpathZ uses internally when libc is not linked.

But also, std.os being so sparse is a recent development. Everything that is now in std.posix was previously part of std.os:

But, again, as the doc comment says, you should basically always try to avoid using getFdPath (and realpath generally) unless you have a really good reason.