commit 6f467e436dab4f6b12e6dc5f29e96f8ce5e060ad (tree)
parent 0d25302d43557d89b868b8925b2e98395d1ebe60
Author: Andrew Kelley <andrew@ziglang.org>
Date: Thu, 26 Mar 2026 21:07:59 -0700
std.Io: move File.CreateFlags to Dir.CreateFileOptions
for naming consistency.
same thing with File.OpenFlags -> Dir.OpenFileFlags
Diffstat:
4 files changed, 129 insertions(+), 134 deletions(-)
diff --git a/lib/std/Io.zig b/lib/std/Io.zig
@@ -160,9 +160,9 @@ pub const VTable = struct {
dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat,
dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat,
dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void,
- dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File,
+ dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileOptions) File.OpenError!File,
dirCreateFileAtomic: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic,
- dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File,
+ dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File,
dirClose: *const fn (?*anyopaque, []const Dir) void,
dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize,
dirRealPath: *const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize,
@@ -211,7 +211,7 @@ pub const VTable = struct {
fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void,
fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void,
- processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File,
+ processExecutableOpen: *const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File,
processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize,
lockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr,
tryLockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr,
diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig
@@ -495,6 +495,72 @@ pub fn closeMany(io: Io, dirs: []const Dir) void {
return io.vtable.dirClose(io.userdata, dirs);
}
+pub const OpenFileOptions = struct {
+ mode: Mode = .read_only,
+ /// Determines the behavior when opening a path that refers to a directory.
+ ///
+ /// If set to true, directories may be opened, but `error.IsDir` is still
+ /// possible in certain scenarios, e.g. attempting to open a directory with
+ /// write permissions.
+ ///
+ /// If set to false, `error.IsDir` will always be returned when opening a directory.
+ ///
+ /// When set to false:
+ /// * On Windows, the behavior is implemented without any extra syscalls.
+ /// * On other operating systems, the behavior is implemented with an additional
+ /// `fstat` syscall.
+ allow_directory: bool = true,
+ /// Indicates intent for only some operations to be performed on this
+ /// opened file:
+ /// * `close`
+ /// * `stat`
+ /// On Linux and FreeBSD, this corresponds to `std.posix.O.PATH`.
+ path_only: bool = false,
+ /// Open the file with an advisory lock to coordinate with other processes
+ /// accessing it at the same time. An exclusive lock will prevent other
+ /// processes from acquiring a lock. A shared lock will prevent other
+ /// processes from acquiring a exclusive lock, but does not prevent
+ /// other process from getting their own shared locks.
+ ///
+ /// The lock is advisory, except on Linux in very specific circumstances[1].
+ /// This means that a process that does not respect the locking API can still get access
+ /// to the file, despite the lock.
+ ///
+ /// On these operating systems, the lock is acquired atomically with
+ /// opening the file:
+ /// * Darwin
+ /// * DragonFlyBSD
+ /// * FreeBSD
+ /// * Haiku
+ /// * NetBSD
+ /// * OpenBSD
+ /// On these operating systems, the lock is acquired via a separate syscall
+ /// after opening the file:
+ /// * Linux
+ /// * Windows
+ ///
+ /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
+ lock: File.Lock = .none,
+ /// Sets whether or not to wait until the file is locked to return. If set to true,
+ /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file
+ /// is available to proceed.
+ lock_nonblocking: bool = false,
+ /// Set this to allow the opened file to automatically become the
+ /// controlling TTY for the current process.
+ allow_ctty: bool = false,
+ follow_symlinks: bool = true,
+
+ pub const Mode = enum { read_only, write_only, read_write };
+
+ pub fn isRead(self: OpenFileOptions) bool {
+ return self.mode != .write_only;
+ }
+
+ pub fn isWrite(self: OpenFileOptions) bool {
+ return self.mode != .read_only;
+ }
+};
+
/// Opens a file for reading or writing, without attempting to create a new file.
///
/// To create a new file, see `createFile`.
@@ -504,15 +570,56 @@ pub fn closeMany(io: Io, dirs: []const Dir) void {
/// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/).
/// On WASI, `sub_path` should be encoded as valid UTF-8.
/// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
-pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
+pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: OpenFileOptions) File.OpenError!File {
return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags);
}
-pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
+pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: OpenFileOptions) File.OpenError!File {
assert(path.isAbsolute(absolute_path));
return openFile(.cwd(), io, absolute_path, flags);
}
+pub const CreateFileOptions = struct {
+ /// Whether the file will be created with read access.
+ read: bool = false,
+ /// If the file already exists, and is a regular file, and the access
+ /// mode allows writing, it will be truncated to length 0.
+ truncate: bool = true,
+ /// Ensures that this open call creates the file, otherwise causes
+ /// `error.PathAlreadyExists` to be returned.
+ exclusive: bool = false,
+ /// Open the file with an advisory lock to coordinate with other processes
+ /// accessing it at the same time. An exclusive lock will prevent other
+ /// processes from acquiring a lock. A shared lock will prevent other
+ /// processes from acquiring a exclusive lock, but does not prevent
+ /// other process from getting their own shared locks.
+ ///
+ /// The lock is advisory, except on Linux in very specific circumstances[1].
+ /// This means that a process that does not respect the locking API can still get access
+ /// to the file, despite the lock.
+ ///
+ /// On these operating systems, the lock is acquired atomically with
+ /// opening the file:
+ /// * Darwin
+ /// * DragonFlyBSD
+ /// * FreeBSD
+ /// * Haiku
+ /// * NetBSD
+ /// * OpenBSD
+ /// On these operating systems, the lock is acquired via a separate syscall
+ /// after opening the file:
+ /// * Linux
+ /// * Windows
+ ///
+ /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
+ lock: File.Lock = .none,
+ /// Sets whether or not to wait until the file is locked to return. If set to true,
+ /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file
+ /// is available to proceed.
+ lock_nonblocking: bool = false,
+ permissions: Permissions = .default_file,
+};
+
/// Creates, opens, or overwrites a file with write access.
///
/// Allocates a resource to be dellocated with `File.close`.
@@ -520,11 +627,11 @@ pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: File.OpenFlags
/// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/).
/// On WASI, `sub_path` should be encoded as valid UTF-8.
/// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
-pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
+pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: CreateFileOptions) File.OpenError!File {
return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags);
}
-pub fn createFileAbsolute(io: Io, absolute_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
+pub fn createFileAbsolute(io: Io, absolute_path: []const u8, flags: CreateFileOptions) File.OpenError!File {
return createFile(.cwd(), io, absolute_path, flags);
}
@@ -534,7 +641,7 @@ pub const WriteFileOptions = struct {
/// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
sub_path: []const u8,
data: []const u8,
- flags: File.CreateFlags = .{},
+ flags: CreateFileOptions = .{},
};
pub const WriteFileError = File.Writer.Error || File.OpenError;
diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig
@@ -142,11 +142,8 @@ pub fn stat(file: File, io: Io) StatError!Stat {
return io.vtable.fileStat(io.userdata, file);
}
-pub const OpenMode = enum {
- read_only,
- write_only,
- read_write,
-};
+/// Deprecated, renamed to `Dir.OpenFileOptions.Mode`.
+pub const OpenMode = Dir.OpenFileOptions.Mode;
pub const Lock = enum {
none,
@@ -154,120 +151,11 @@ pub const Lock = enum {
exclusive,
};
-pub const OpenFlags = struct {
- mode: OpenMode = .read_only,
-
- /// Determines the behavior when opening a path that refers to a directory.
- ///
- /// If set to true, directories may be opened, but `error.IsDir` is still
- /// possible in certain scenarios, e.g. attempting to open a directory with
- /// write permissions.
- ///
- /// If set to false, `error.IsDir` will always be returned when opening a directory.
- ///
- /// When set to false:
- /// * On Windows, the behavior is implemented without any extra syscalls.
- /// * On other operating systems, the behavior is implemented with an additional
- /// `fstat` syscall.
- allow_directory: bool = true,
- /// Indicates intent for only some operations to be performed on this
- /// opened file:
- /// * `close`
- /// * `stat`
- /// On Linux and FreeBSD, this corresponds to `std.posix.O.PATH`.
- path_only: bool = false,
-
- /// Open the file with an advisory lock to coordinate with other processes
- /// accessing it at the same time. An exclusive lock will prevent other
- /// processes from acquiring a lock. A shared lock will prevent other
- /// processes from acquiring a exclusive lock, but does not prevent
- /// other process from getting their own shared locks.
- ///
- /// The lock is advisory, except on Linux in very specific circumstances[1].
- /// This means that a process that does not respect the locking API can still get access
- /// to the file, despite the lock.
- ///
- /// On these operating systems, the lock is acquired atomically with
- /// opening the file:
- /// * Darwin
- /// * DragonFlyBSD
- /// * FreeBSD
- /// * Haiku
- /// * NetBSD
- /// * OpenBSD
- /// On these operating systems, the lock is acquired via a separate syscall
- /// after opening the file:
- /// * Linux
- /// * Windows
- ///
- /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
- lock: Lock = .none,
-
- /// Sets whether or not to wait until the file is locked to return. If set to true,
- /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file
- /// is available to proceed.
- lock_nonblocking: bool = false,
-
- /// Set this to allow the opened file to automatically become the
- /// controlling TTY for the current process.
- allow_ctty: bool = false,
-
- follow_symlinks: bool = true,
-
- pub fn isRead(self: OpenFlags) bool {
- return self.mode != .write_only;
- }
+/// Deprecated, renamed to `Dir.OpenFileOptions`
+pub const OpenFlags = Dir.OpenFileOptions;
- pub fn isWrite(self: OpenFlags) bool {
- return self.mode != .read_only;
- }
-};
-
-pub const CreateFlags = struct {
- /// Whether the file will be created with read access.
- read: bool = false,
-
- /// If the file already exists, and is a regular file, and the access
- /// mode allows writing, it will be truncated to length 0.
- truncate: bool = true,
-
- /// Ensures that this open call creates the file, otherwise causes
- /// `error.PathAlreadyExists` to be returned.
- exclusive: bool = false,
-
- /// Open the file with an advisory lock to coordinate with other processes
- /// accessing it at the same time. An exclusive lock will prevent other
- /// processes from acquiring a lock. A shared lock will prevent other
- /// processes from acquiring a exclusive lock, but does not prevent
- /// other process from getting their own shared locks.
- ///
- /// The lock is advisory, except on Linux in very specific circumstances[1].
- /// This means that a process that does not respect the locking API can still get access
- /// to the file, despite the lock.
- ///
- /// On these operating systems, the lock is acquired atomically with
- /// opening the file:
- /// * Darwin
- /// * DragonFlyBSD
- /// * FreeBSD
- /// * Haiku
- /// * NetBSD
- /// * OpenBSD
- /// On these operating systems, the lock is acquired via a separate syscall
- /// after opening the file:
- /// * Linux
- /// * Windows
- ///
- /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt
- lock: Lock = .none,
-
- /// Sets whether or not to wait until the file is locked to return. If set to true,
- /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file
- /// is available to proceed.
- lock_nonblocking: bool = false,
-
- permissions: Permissions = .default_file,
-};
+/// Deprecated, renamed to `Dir.CreateFileOptions`.
+pub const CreateFlags = Dir.CreateFileOptions;
pub const OpenError = error{
PipeBusy,
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -4217,7 +4217,7 @@ fn dirCreateFilePosix(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.CreateFlags,
+ flags: Dir.CreateFileOptions,
) File.OpenError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
@@ -4385,7 +4385,7 @@ fn dirCreateFileWindows(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.CreateFlags,
+ flags: Dir.CreateFileOptions,
) File.OpenError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
@@ -4535,7 +4535,7 @@ fn dirCreateFileWasi(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.CreateFlags,
+ flags: Dir.CreateFileOptions,
) File.OpenError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
@@ -4785,7 +4785,7 @@ fn dirOpenFilePosix(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.OpenFlags,
+ flags: Dir.OpenFileOptions,
) File.OpenError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
@@ -4979,7 +4979,7 @@ fn dirOpenFileWindows(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.OpenFlags,
+ flags: Dir.OpenFileOptions,
) File.OpenError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
@@ -4992,7 +4992,7 @@ fn dirOpenFileWindows(
pub fn dirOpenFileWtf16(
dir_handle: ?windows.HANDLE,
sub_path_w: []const u16,
- flags: File.OpenFlags,
+ flags: Dir.OpenFileOptions,
) File.OpenError!File {
const allow_directory = flags.allow_directory and !flags.isWrite();
if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir;
@@ -5129,7 +5129,7 @@ fn dirOpenFileWasi(
userdata: ?*anyopaque,
dir: Dir,
sub_path: []const u8,
- flags: File.OpenFlags,
+ flags: Dir.OpenFileOptions,
) File.OpenError!File {
if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags);
const t: *Threaded = @ptrCast(@alignCast(userdata));
@@ -10193,7 +10193,7 @@ fn posixSeekTo(fd: posix.fd_t, offset: u64) File.SeekError!void {
}
}
-fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) process.OpenExecutableError!File {
+fn processExecutableOpen(userdata: ?*anyopaque, flags: Dir.OpenFileOptions) process.OpenExecutableError!File {
const t: *Threaded = @ptrCast(@alignCast(userdata));
switch (native_os) {
.wasi => return error.OperationUnsupported,