zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mlib/std/Io.zig | 6+++---
Mlib/std/Io/Dir.zig | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mlib/std/Io/File.zig | 124++++---------------------------------------------------------------------------
Mlib/std/Io/Threaded.zig | 16++++++++--------
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,