File system: best practices

The one platform it likely won’t work on is UEFI but I’m not sure that the std.fs API works with UEFI anyway. Every other platform that I’m aware of supports / as the path separator, and any cross-platform std.fs API not properly handling / as a path separator should be treated as a bug IMO.

Note also that fs/test.zig actually tests that both / and \ work on Windows as of this commit (on Windows, all tests that use testWithAllSupportedPathTypes are run once with / as the separator and again with \ as the separator).

If you’d like to avoid going through cwd, then you can use one of the std.fs.<something>Absolute functions. This point, that users may have reason to avoid cwd, is the reason that those functions exist, but it’s also worth noting that many of the Absolute suffixed functions are currently nothing but wrappers around the Dir function, so in practical terms you might not actually always avoid the cwd() call:

Another thing worth noting is that currently, on every platform (including WASI), std.fs.cwd() doesn’t actually make any syscalls by default:

  • On Windows, a handle to the current directory can be retrieved from the Process Environment Block
  • On POSIX systems, it returns a Dir with an fd containing a special constant AT_FDCWD. The fact that this is not a real fd can cause problems (and there are bugs if you try to use the return of cwd() with certain APIs. How best to handle this is still up in the air)
  • On WASI, there is no actual CWD, so by default Zig just returns the fd of the first preopen. If this is not what you want, you can customize the behavior of cwd() for WASI via a root std_options decl and providing a wasiCwd function.

This means that a cwd() call is effectively free, which makes it a nice common-denominator starting point for the Dir APIs, even if the cwd doesn’t end up being used (i.e. you’re using an absolute path). If cwd() wasn’t a cheap call (or could fail), then it seems pretty likely that cwd() calls wouldn’t be so ubiquitous.

4 Likes