-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove fooAbsolute
functions from std.fs
#16736
Comments
In my eyes the most useful path forward would be 3 variants: One which supports any path (checks I do generally agree with discouraging absolute path operations; every |
Just to be clear: The I could be wrong, but I believe there is no inherent benefit to splitting functions into absolute-only/relative-only variations. If you have a particular use-case in mind, or an implementation that a relative-only/absolute-only function could take advantage of, then please provide it. The The idea here is that something like this (which works as intended with status quo Zig): const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const allocator = gpa.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len < 2) return error.MissingArgs;
const filename = args[1];
const contents = try std.fs.cwd().readFileAlloc(allocator, filename, std.math.maxInt(usize));
defer allocator.free(contents);
std.debug.print("contents len: {}\ncontents:\n{s}\n", .{ contents.len, contents });
} will work for any target and any path type provided by the user:
And this is even true for WASI:
Having relative-only/absolute-only functions would just make it easier to write a version of this code that doesn't work for some targets for no discernible benefit (but, again, I could be wrong about that). |
I thought there was the point of WASI only understanding handle-relative paths.
I'm not particularly well-versed in the topic, and it seems like you thought about this more than I have. My 2c regardless: The only benefit I would see is easier explicitness (+ corresponding bug safety), providing the (And I still don't quite understand the comment/usage of/about |
This wouldn't actually gain us anything I don't think, since the underlying syscalls already handle this type of stuff for us. For example, openat:
Then you are free to add a EDIT: And 'absolute paths are not supported when targeting WASI' is not actually fully true in practical terms IIUC. As mentioned in the OP, when linking
The only point there was showing that the |
Here's another idea that might be worth consideration. Adding Such an interface also lends itself to extensibility, namely, I could imagine adding a |
@marler8997 I'm still struggling to see why // will panic/cause UB if path is not absolute
var file = try std.fs.openFileAbsolute(path, .{}); or // will ??? if path is not absolute
var file = try root.openFile(path, .{}); would be preferable to // handle non-absolute paths in whatever way makes sense for your program
// if there's some reason for that to be necessary
std.debug.assert(std.fs.path.isAbsolute(path));
// or
if (!std.fs.path.isAbsolute(path)) return error.NonAbsolutePath;
var file = try std.fs.cwd().openFile(path); am I missing something that makes requiring absolute paths a common use case? But besides that, there's no singular root on e.g. Windows ( |
See #16743 for how removing the EDIT: In making the changes in that PR, I came across another reason why the |
Comment from the peanut gallery: Encouraging the explicit passing of directory handles is consistent with passing allocators and could have many of the same advantages: better testability (i.e. passing handles to in memory dirs), test dir implementations with file descriptor leak detection, nudging library developers toward portability, etc. |
I think this might actually be one of the biggest benefits of going all in on the In hindsight, that comment isn't technically correct as the WASI implementation could try to infer a |
I disagree insofar, as this will leak directory handles into parallel spawned processes on xor force a full mutex to restrict process spawn xor close all unwanted ones (communicating via environment or stdin) with unnecessary expensive syscalls for every close. This might be no problem in the Zig unit test system, since only 1 child is spawned. However, users wanting to spawn children of children might not want to have those drawbacks. |
Closing. The reasoning can be found here: While I think the API might benefit from the removal of |
This is a proposal regarding the
Absolute
suffixed functions in thestd.fs
namespace, see https://ziglang.org/documentation/master/std/#A;std:fsFirst, here's the 'soft' version of this proposal:
Remove any
fooAbsolute
functions that are purely a wrapper aroundDir.foo
Many of the
fooAbsolute
functions are purely wrappers around the relevantDir
function. For example, here'sopenDirAbsolute
:zig/lib/std/fs.zig
Lines 2711 to 2714 in c6e2e1a
The only thing these functions add are assertions that the path is absolute, but those can easily be done by the user at the callsite instead.
Note also that pretty much all
Absolute
functions have poor test coverage to the point that some will give a compile error if anyone tried to actually use them (e.g. on Windows anything that tries to call the no-longer-existingos.windows.cStrToWin32PrefixedFileW
function [these functions have never worked since their introduction in #5879 which ended up removingcStrToWin32PrefixedFileW
before it was merged but left some calls of it around])I believe the above should be fairly uncontroversial.
Now, for the real proposal:
Remove all
fooAbsolute
functions fromstd.fs
This is something of a counter-proposal to #7540
This proposal has two parts:
Dir
APIs should be able to handle both relative and absolute paths (this is already the case AFAIK)Dir
APIs should be removed in favor ofDir
-based APIsThis is something that
std.fs
has been moving towards slowly, but it's never been formalized and so the currentstd.fs
is a bit confused (and can be confusing for those new to Zig, since the most libc-like APIs are thefooAbsolute
ones). Removing theAbsolute
APIs would allow Zig to communicate the design of thefs
API more clearly and lead more people to write code/libraries that get the benefits of theDir
-based API for free.Why
Dir
-based for everything?My understanding of the reasoning for the
Dir
-based design is the following:1. For "better general protection against Time Of Check, Time Of Use bugs across all Zig codebases"
From #3813, where things being more
Dir
-based was initiated:Here's an example:
With a non-
Dir
-based API, the above might instead be written as something like:2. For better cross-platform compatibility by default
(my understanding is that this is mostly just a nice side-benefit, and wasn't originally a reason for the
fs
API design)Platforms like WASI don't have the concept of an absolute path, so any API without an explicit
Dir
would exclude that code from being able to target WASI (or require a decent amount of compatibility code to infer aDir
from any given path when targeting WASI). From https://github.com/WebAssembly/wasi-filesystem:With the Zig filesystem API being designed to encourage the same thing (every filesystem function having an associated
Dir
), Zig code will be able to essentially target WASI by default without needing to do some of the contortions that something like wasi-libc has to do to support the 'normal' path-based APIs.Note: WASI also doesn't have the concept of a
cwd
. Currently,std.fs.cwd()
when targeting WASI will treat the first preopen as thecwd
by default, but that behavior can be changed by supplying a customwasiCwd
function via astd_options
struct in the root source file.If the strong version of this proposal is accepted, then the only top-level functions in
std.fs
that would remain would be:atomicSymLink
, although it seems very possible this could/should be made into aDir
functioncwd
getAppDataDir
openSelfExe
rename
/renameW
/renameZ
(these useDir
s)selfExeDirPath
/selfExeDirPathAlloc
selfExePath
/selfExePathAlloc
/selfExePathW
See #16743 for how removing the
Absolute
suffixedstd.fs
functions would affect the Zig codebase.EDIT: In making the changes in that PR, I came across another reason why the
Absolute
versions aren't very useful: theAbsolute
terminology is overloaded and it's hard/impossible to tell why theAbsolute
variant is being used--is it being used just because the programmer knows the path happens to be absolute, or is it being used because the programmer knows the path must be absolute for the code to work correctly? Removing theAbsolute
variation will remove this ambiguity since the programmer will be forced to make their intentions more explicit if they want to assert/check that a given path is absolute.The text was updated successfully, but these errors were encountered: