| author | |
| committer | |
| log | 2d3694ab42b73ba09124d5f1ddbfd9adaea79c47 |
| tree | 8c0adc21784e13f0c7a5ce9d88167b84c8c62b2c |
| parent | 1f79a9e4e300affd111b51ec172bbeff42ca755a |
| parent | 2e4482cd14d6af958c2e16d7db4d6cf73bd043b8 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/316845 files changed, 181 insertions(+), 175 deletions(-)
lib/std/Io.zig+3-3| ... | @@ -160,9 +160,9 @@ pub const VTable = struct { | ... | @@ -160,9 +160,9 @@ pub const VTable = struct { |
| 160 | dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, | 160 | dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, |
| 161 | dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat, | 161 | dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat, |
| 162 | dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void, | 162 | dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void, |
| 163 | dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File, | 163 | dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileOptions) File.OpenError!File, |
| 164 | dirCreateFileAtomic: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic, | 164 | dirCreateFileAtomic: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic, |
| 165 | dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File, | 165 | dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File, |
| 166 | dirClose: *const fn (?*anyopaque, []const Dir) void, | 166 | dirClose: *const fn (?*anyopaque, []const Dir) void, |
| 167 | dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize, | 167 | dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize, |
| 168 | dirRealPath: *const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize, | 168 | dirRealPath: *const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize, |
| ... | @@ -211,7 +211,7 @@ pub const VTable = struct { | ... | @@ -211,7 +211,7 @@ pub const VTable = struct { |
| 211 | fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void, | 211 | fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void, |
| 212 | fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void, | 212 | fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void, |
| 213 | 213 | ||
| 214 | processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File, | 214 | processExecutableOpen: *const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File, |
| 215 | processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize, | 215 | processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize, |
| 216 | lockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr, | 216 | lockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr, |
| 217 | tryLockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr, | 217 | tryLockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr, |
lib/std/Io/Dir.zig+122-7| ... | @@ -495,6 +495,76 @@ pub fn closeMany(io: Io, dirs: []const Dir) void { | ... | @@ -495,6 +495,76 @@ pub fn closeMany(io: Io, dirs: []const Dir) void { |
| 495 | return io.vtable.dirClose(io.userdata, dirs); | 495 | return io.vtable.dirClose(io.userdata, dirs); |
| 496 | } | 496 | } |
| 497 | 497 | ||
| 498 | pub const OpenFileOptions = struct { | ||
| 499 | mode: Mode = .read_only, | ||
| 500 | /// Determines the behavior when opening a path that refers to a directory. | ||
| 501 | /// | ||
| 502 | /// If set to true, directories may be opened, but `error.IsDir` is still | ||
| 503 | /// possible in certain scenarios, e.g. attempting to open a directory with | ||
| 504 | /// write permissions. | ||
| 505 | /// | ||
| 506 | /// If set to false, `error.IsDir` will always be returned when opening a directory. | ||
| 507 | /// | ||
| 508 | /// When set to false: | ||
| 509 | /// * On Windows, the behavior is implemented without any extra syscalls. | ||
| 510 | /// * On other operating systems, the behavior is implemented with an additional | ||
| 511 | /// `fstat` syscall. | ||
| 512 | allow_directory: bool = true, | ||
| 513 | /// Indicates intent for only some operations to be performed on this | ||
| 514 | /// opened file: | ||
| 515 | /// * `close` | ||
| 516 | /// * `stat` | ||
| 517 | /// On Linux and FreeBSD, this corresponds to `std.posix.O.PATH`. | ||
| 518 | path_only: bool = false, | ||
| 519 | /// Open the file with an advisory lock to coordinate with other processes | ||
| 520 | /// accessing it at the same time. An exclusive lock will prevent other | ||
| 521 | /// processes from acquiring a lock. A shared lock will prevent other | ||
| 522 | /// processes from acquiring a exclusive lock, but does not prevent | ||
| 523 | /// other process from getting their own shared locks. | ||
| 524 | /// | ||
| 525 | /// The lock is advisory, except on Linux in very specific circumstances[1]. | ||
| 526 | /// This means that a process that does not respect the locking API can still get access | ||
| 527 | /// to the file, despite the lock. | ||
| 528 | /// | ||
| 529 | /// On these operating systems, the lock is acquired atomically with | ||
| 530 | /// opening the file: | ||
| 531 | /// * Darwin | ||
| 532 | /// * DragonFlyBSD | ||
| 533 | /// * FreeBSD | ||
| 534 | /// * Haiku | ||
| 535 | /// * NetBSD | ||
| 536 | /// * OpenBSD | ||
| 537 | /// On these operating systems, the lock is acquired via a separate syscall | ||
| 538 | /// after opening the file: | ||
| 539 | /// * Linux | ||
| 540 | /// * Windows | ||
| 541 | /// | ||
| 542 | /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt | ||
| 543 | lock: File.Lock = .none, | ||
| 544 | /// Sets whether or not to wait until the file is locked to return. If set to true, | ||
| 545 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | ||
| 546 | /// is available to proceed. | ||
| 547 | lock_nonblocking: bool = false, | ||
| 548 | /// Set this to allow the opened file to automatically become the | ||
| 549 | /// controlling TTY for the current process. | ||
| 550 | allow_ctty: bool = false, | ||
| 551 | follow_symlinks: bool = true, | ||
| 552 | /// If supported by the operating system, attempted path resolution that | ||
| 553 | /// would escape the directory instead returns `error.AccessDenied`. If | ||
| 554 | /// unsupported, this option is ignored. | ||
| 555 | resolve_beneath: bool = false, | ||
| 556 | |||
| 557 | pub const Mode = enum { read_only, write_only, read_write }; | ||
| 558 | |||
| 559 | pub fn isRead(self: OpenFileOptions) bool { | ||
| 560 | return self.mode != .write_only; | ||
| 561 | } | ||
| 562 | |||
| 563 | pub fn isWrite(self: OpenFileOptions) bool { | ||
| 564 | return self.mode != .read_only; | ||
| 565 | } | ||
| 566 | }; | ||
| 567 | |||
| 498 | /// Opens a file for reading or writing, without attempting to create a new file. | 568 | /// Opens a file for reading or writing, without attempting to create a new file. |
| 499 | /// | 569 | /// |
| 500 | /// To create a new file, see `createFile`. | 570 | /// To create a new file, see `createFile`. |
| ... | @@ -504,15 +574,60 @@ pub fn closeMany(io: Io, dirs: []const Dir) void { | ... | @@ -504,15 +574,60 @@ pub fn closeMany(io: Io, dirs: []const Dir) void { |
| 504 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | 574 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 505 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | 575 | /// On WASI, `sub_path` should be encoded as valid UTF-8. |
| 506 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | 576 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 507 | pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { | 577 | pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, options: OpenFileOptions) File.OpenError!File { |
| 508 | return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags); | 578 | return io.vtable.dirOpenFile(io.userdata, dir, sub_path, options); |
| 509 | } | 579 | } |
| 510 | 580 | ||
| 511 | pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: File.OpenFlags) File.OpenError!File { | 581 | pub fn openFileAbsolute(io: Io, absolute_path: []const u8, options: OpenFileOptions) File.OpenError!File { |
| 512 | assert(path.isAbsolute(absolute_path)); | 582 | assert(path.isAbsolute(absolute_path)); |
| 513 | return openFile(.cwd(), io, absolute_path, flags); | 583 | return openFile(.cwd(), io, absolute_path, options); |
| 514 | } | 584 | } |
| 515 | 585 | ||
| 586 | pub const CreateFileOptions = struct { | ||
| 587 | /// Whether the file will be created with read access. | ||
| 588 | read: bool = false, | ||
| 589 | /// If the file already exists, and is a regular file, and the access | ||
| 590 | /// mode allows writing, it will be truncated to length 0. | ||
| 591 | truncate: bool = true, | ||
| 592 | /// Ensures that this open call creates the file, otherwise causes | ||
| 593 | /// `error.PathAlreadyExists` to be returned. | ||
| 594 | exclusive: bool = false, | ||
| 595 | /// Open the file with an advisory lock to coordinate with other processes | ||
| 596 | /// accessing it at the same time. An exclusive lock will prevent other | ||
| 597 | /// processes from acquiring a lock. A shared lock will prevent other | ||
| 598 | /// processes from acquiring a exclusive lock, but does not prevent | ||
| 599 | /// other process from getting their own shared locks. | ||
| 600 | /// | ||
| 601 | /// The lock is advisory, except on Linux in very specific circumstances[1]. | ||
| 602 | /// This means that a process that does not respect the locking API can still get access | ||
| 603 | /// to the file, despite the lock. | ||
| 604 | /// | ||
| 605 | /// On these operating systems, the lock is acquired atomically with | ||
| 606 | /// opening the file: | ||
| 607 | /// * Darwin | ||
| 608 | /// * DragonFlyBSD | ||
| 609 | /// * FreeBSD | ||
| 610 | /// * Haiku | ||
| 611 | /// * NetBSD | ||
| 612 | /// * OpenBSD | ||
| 613 | /// On these operating systems, the lock is acquired via a separate syscall | ||
| 614 | /// after opening the file: | ||
| 615 | /// * Linux | ||
| 616 | /// * Windows | ||
| 617 | /// | ||
| 618 | /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt | ||
| 619 | lock: File.Lock = .none, | ||
| 620 | /// Sets whether or not to wait until the file is locked to return. If set to true, | ||
| 621 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | ||
| 622 | /// is available to proceed. | ||
| 623 | lock_nonblocking: bool = false, | ||
| 624 | permissions: Permissions = .default_file, | ||
| 625 | /// If supported by the operating system, attempted path resolution that | ||
| 626 | /// would escape the directory instead returns `error.AccessDenied`. If | ||
| 627 | /// unsupported, this option is ignored. | ||
| 628 | resolve_beneath: bool = false, | ||
| 629 | }; | ||
| 630 | |||
| 516 | /// Creates, opens, or overwrites a file with write access. | 631 | /// Creates, opens, or overwrites a file with write access. |
| 517 | /// | 632 | /// |
| 518 | /// Allocates a resource to be dellocated with `File.close`. | 633 | /// Allocates a resource to be dellocated with `File.close`. |
| ... | @@ -520,11 +635,11 @@ pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: File.OpenFlags | ... | @@ -520,11 +635,11 @@ pub fn openFileAbsolute(io: Io, absolute_path: []const u8, flags: File.OpenFlags |
| 520 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | 635 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 521 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | 636 | /// On WASI, `sub_path` should be encoded as valid UTF-8. |
| 522 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | 637 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 523 | pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { | 638 | pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: CreateFileOptions) File.OpenError!File { |
| 524 | return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags); | 639 | return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags); |
| 525 | } | 640 | } |
| 526 | 641 | ||
| 527 | pub fn createFileAbsolute(io: Io, absolute_path: []const u8, flags: File.CreateFlags) File.OpenError!File { | 642 | pub fn createFileAbsolute(io: Io, absolute_path: []const u8, flags: CreateFileOptions) File.OpenError!File { |
| 528 | return createFile(.cwd(), io, absolute_path, flags); | 643 | return createFile(.cwd(), io, absolute_path, flags); |
| 529 | } | 644 | } |
| 530 | 645 | ||
| ... | @@ -534,7 +649,7 @@ pub const WriteFileOptions = struct { | ... | @@ -534,7 +649,7 @@ pub const WriteFileOptions = struct { |
| 534 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | 649 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 535 | sub_path: []const u8, | 650 | sub_path: []const u8, |
| 536 | data: []const u8, | 651 | data: []const u8, |
| 537 | flags: File.CreateFlags = .{}, | 652 | flags: CreateFileOptions = .{}, |
| 538 | }; | 653 | }; |
| 539 | 654 | ||
| 540 | pub const WriteFileError = File.Writer.Error || File.OpenError; | 655 | pub const WriteFileError = File.Writer.Error || File.OpenError; |
lib/std/Io/File.zig+6-118| ... | @@ -142,11 +142,8 @@ pub fn stat(file: File, io: Io) StatError!Stat { | ... | @@ -142,11 +142,8 @@ pub fn stat(file: File, io: Io) StatError!Stat { |
| 142 | return io.vtable.fileStat(io.userdata, file); | 142 | return io.vtable.fileStat(io.userdata, file); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | pub const OpenMode = enum { | 145 | /// Deprecated, renamed to `Dir.OpenFileOptions.Mode`. |
| 146 | read_only, | 146 | pub const OpenMode = Dir.OpenFileOptions.Mode; |
| 147 | write_only, | ||
| 148 | read_write, | ||
| 149 | }; | ||
| 150 | 147 | ||
| 151 | pub const Lock = enum { | 148 | pub const Lock = enum { |
| 152 | none, | 149 | none, |
| ... | @@ -154,120 +151,11 @@ pub const Lock = enum { | ... | @@ -154,120 +151,11 @@ pub const Lock = enum { |
| 154 | exclusive, | 151 | exclusive, |
| 155 | }; | 152 | }; |
| 156 | 153 | ||
| 157 | pub const OpenFlags = struct { | 154 | /// Deprecated, renamed to `Dir.OpenFileOptions` |
| 158 | mode: OpenMode = .read_only, | 155 | pub const OpenFlags = Dir.OpenFileOptions; |
| 159 | |||
| 160 | /// Determines the behavior when opening a path that refers to a directory. | ||
| 161 | /// | ||
| 162 | /// If set to true, directories may be opened, but `error.IsDir` is still | ||
| 163 | /// possible in certain scenarios, e.g. attempting to open a directory with | ||
| 164 | /// write permissions. | ||
| 165 | /// | ||
| 166 | /// If set to false, `error.IsDir` will always be returned when opening a directory. | ||
| 167 | /// | ||
| 168 | /// When set to false: | ||
| 169 | /// * On Windows, the behavior is implemented without any extra syscalls. | ||
| 170 | /// * On other operating systems, the behavior is implemented with an additional | ||
| 171 | /// `fstat` syscall. | ||
| 172 | allow_directory: bool = true, | ||
| 173 | /// Indicates intent for only some operations to be performed on this | ||
| 174 | /// opened file: | ||
| 175 | /// * `close` | ||
| 176 | /// * `stat` | ||
| 177 | /// On Linux and FreeBSD, this corresponds to `std.posix.O.PATH`. | ||
| 178 | path_only: bool = false, | ||
| 179 | |||
| 180 | /// Open the file with an advisory lock to coordinate with other processes | ||
| 181 | /// accessing it at the same time. An exclusive lock will prevent other | ||
| 182 | /// processes from acquiring a lock. A shared lock will prevent other | ||
| 183 | /// processes from acquiring a exclusive lock, but does not prevent | ||
| 184 | /// other process from getting their own shared locks. | ||
| 185 | /// | ||
| 186 | /// The lock is advisory, except on Linux in very specific circumstances[1]. | ||
| 187 | /// This means that a process that does not respect the locking API can still get access | ||
| 188 | /// to the file, despite the lock. | ||
| 189 | /// | ||
| 190 | /// On these operating systems, the lock is acquired atomically with | ||
| 191 | /// opening the file: | ||
| 192 | /// * Darwin | ||
| 193 | /// * DragonFlyBSD | ||
| 194 | /// * FreeBSD | ||
| 195 | /// * Haiku | ||
| 196 | /// * NetBSD | ||
| 197 | /// * OpenBSD | ||
| 198 | /// On these operating systems, the lock is acquired via a separate syscall | ||
| 199 | /// after opening the file: | ||
| 200 | /// * Linux | ||
| 201 | /// * Windows | ||
| 202 | /// | ||
| 203 | /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt | ||
| 204 | lock: Lock = .none, | ||
| 205 | |||
| 206 | /// Sets whether or not to wait until the file is locked to return. If set to true, | ||
| 207 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | ||
| 208 | /// is available to proceed. | ||
| 209 | lock_nonblocking: bool = false, | ||
| 210 | |||
| 211 | /// Set this to allow the opened file to automatically become the | ||
| 212 | /// controlling TTY for the current process. | ||
| 213 | allow_ctty: bool = false, | ||
| 214 | |||
| 215 | follow_symlinks: bool = true, | ||
| 216 | |||
| 217 | pub fn isRead(self: OpenFlags) bool { | ||
| 218 | return self.mode != .write_only; | ||
| 219 | } | ||
| 220 | 156 | ||
| 221 | pub fn isWrite(self: OpenFlags) bool { | 157 | /// Deprecated, renamed to `Dir.CreateFileOptions`. |
| 222 | return self.mode != .read_only; | 158 | pub const CreateFlags = Dir.CreateFileOptions; |
| 223 | } | ||
| 224 | }; | ||
| 225 | |||
| 226 | pub const CreateFlags = struct { | ||
| 227 | /// Whether the file will be created with read access. | ||
| 228 | read: bool = false, | ||
| 229 | |||
| 230 | /// If the file already exists, and is a regular file, and the access | ||
| 231 | /// mode allows writing, it will be truncated to length 0. | ||
| 232 | truncate: bool = true, | ||
| 233 | |||
| 234 | /// Ensures that this open call creates the file, otherwise causes | ||
| 235 | /// `error.PathAlreadyExists` to be returned. | ||
| 236 | exclusive: bool = false, | ||
| 237 | |||
| 238 | /// Open the file with an advisory lock to coordinate with other processes | ||
| 239 | /// accessing it at the same time. An exclusive lock will prevent other | ||
| 240 | /// processes from acquiring a lock. A shared lock will prevent other | ||
| 241 | /// processes from acquiring a exclusive lock, but does not prevent | ||
| 242 | /// other process from getting their own shared locks. | ||
| 243 | /// | ||
| 244 | /// The lock is advisory, except on Linux in very specific circumstances[1]. | ||
| 245 | /// This means that a process that does not respect the locking API can still get access | ||
| 246 | /// to the file, despite the lock. | ||
| 247 | /// | ||
| 248 | /// On these operating systems, the lock is acquired atomically with | ||
| 249 | /// opening the file: | ||
| 250 | /// * Darwin | ||
| 251 | /// * DragonFlyBSD | ||
| 252 | /// * FreeBSD | ||
| 253 | /// * Haiku | ||
| 254 | /// * NetBSD | ||
| 255 | /// * OpenBSD | ||
| 256 | /// On these operating systems, the lock is acquired via a separate syscall | ||
| 257 | /// after opening the file: | ||
| 258 | /// * Linux | ||
| 259 | /// * Windows | ||
| 260 | /// | ||
| 261 | /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt | ||
| 262 | lock: Lock = .none, | ||
| 263 | |||
| 264 | /// Sets whether or not to wait until the file is locked to return. If set to true, | ||
| 265 | /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file | ||
| 266 | /// is available to proceed. | ||
| 267 | lock_nonblocking: bool = false, | ||
| 268 | |||
| 269 | permissions: Permissions = .default_file, | ||
| 270 | }; | ||
| 271 | 159 | ||
| 272 | pub const OpenError = error{ | 160 | pub const OpenError = error{ |
| 273 | PipeBusy, | 161 | PipeBusy, |
lib/std/Io/Threaded.zig+48-46| ... | @@ -4217,7 +4217,7 @@ fn dirCreateFilePosix( | ... | @@ -4217,7 +4217,7 @@ fn dirCreateFilePosix( |
| 4217 | userdata: ?*anyopaque, | 4217 | userdata: ?*anyopaque, |
| 4218 | dir: Dir, | 4218 | dir: Dir, |
| 4219 | sub_path: []const u8, | 4219 | sub_path: []const u8, |
| 4220 | flags: File.CreateFlags, | 4220 | options: Dir.CreateFileOptions, |
| 4221 | ) File.OpenError!File { | 4221 | ) File.OpenError!File { |
| 4222 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4222 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4223 | _ = t; | 4223 | _ = t; |
| ... | @@ -4225,34 +4225,35 @@ fn dirCreateFilePosix( | ... | @@ -4225,34 +4225,35 @@ fn dirCreateFilePosix( |
| 4225 | var path_buffer: [posix.PATH_MAX]u8 = undefined; | 4225 | var path_buffer: [posix.PATH_MAX]u8 = undefined; |
| 4226 | const sub_path_posix = try pathToPosix(sub_path, &path_buffer); | 4226 | const sub_path_posix = try pathToPosix(sub_path, &path_buffer); |
| 4227 | 4227 | ||
| 4228 | var os_flags: posix.O = .{ | 4228 | var flags: posix.O = .{ |
| 4229 | .ACCMODE = if (flags.read) .RDWR else .WRONLY, | 4229 | .ACCMODE = if (options.read) .RDWR else .WRONLY, |
| 4230 | .CREAT = true, | 4230 | .CREAT = true, |
| 4231 | .TRUNC = flags.truncate, | 4231 | .TRUNC = options.truncate, |
| 4232 | .EXCL = flags.exclusive, | 4232 | .EXCL = options.exclusive, |
| 4233 | }; | 4233 | }; |
| 4234 | if (@hasField(posix.O, "LARGEFILE")) os_flags.LARGEFILE = true; | 4234 | if (@hasField(posix.O, "LARGEFILE")) flags.LARGEFILE = true; |
| 4235 | if (@hasField(posix.O, "CLOEXEC")) os_flags.CLOEXEC = true; | 4235 | if (@hasField(posix.O, "CLOEXEC")) flags.CLOEXEC = true; |
| 4236 | if (@hasField(posix.O, "RESOLVE_BENEATH")) flags.RESOLVE_BENEATH = options.resolve_beneath; | ||
| 4236 | 4237 | ||
| 4237 | // Use the O locking flags if the os supports them to acquire the lock | 4238 | // Use the O locking flags if the os supports them to acquire the lock |
| 4238 | // atomically. Note that the NONBLOCK flag is removed after the openat() | 4239 | // atomically. Note that the NONBLOCK flag is removed after the openat() |
| 4239 | // call is successful. | 4240 | // call is successful. |
| 4240 | if (have_flock_open_flags) switch (flags.lock) { | 4241 | if (have_flock_open_flags) switch (options.lock) { |
| 4241 | .none => {}, | 4242 | .none => {}, |
| 4242 | .shared => { | 4243 | .shared => { |
| 4243 | os_flags.SHLOCK = true; | 4244 | flags.SHLOCK = true; |
| 4244 | os_flags.NONBLOCK = flags.lock_nonblocking; | 4245 | flags.NONBLOCK = options.lock_nonblocking; |
| 4245 | }, | 4246 | }, |
| 4246 | .exclusive => { | 4247 | .exclusive => { |
| 4247 | os_flags.EXLOCK = true; | 4248 | flags.EXLOCK = true; |
| 4248 | os_flags.NONBLOCK = flags.lock_nonblocking; | 4249 | flags.NONBLOCK = options.lock_nonblocking; |
| 4249 | }, | 4250 | }, |
| 4250 | }; | 4251 | }; |
| 4251 | 4252 | ||
| 4252 | const fd: posix.fd_t = fd: { | 4253 | const fd: posix.fd_t = fd: { |
| 4253 | const syscall: Syscall = try .start(); | 4254 | const syscall: Syscall = try .start(); |
| 4254 | while (true) { | 4255 | while (true) { |
| 4255 | const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode()); | 4256 | const rc = openat_sym(dir.handle, sub_path_posix, flags, options.permissions.toMode()); |
| 4256 | switch (posix.errno(rc)) { | 4257 | switch (posix.errno(rc)) { |
| 4257 | .SUCCESS => { | 4258 | .SUCCESS => { |
| 4258 | syscall.finish(); | 4259 | syscall.finish(); |
| ... | @@ -4298,9 +4299,9 @@ fn dirCreateFilePosix( | ... | @@ -4298,9 +4299,9 @@ fn dirCreateFilePosix( |
| 4298 | }; | 4299 | }; |
| 4299 | errdefer closeFd(fd); | 4300 | errdefer closeFd(fd); |
| 4300 | 4301 | ||
| 4301 | if (have_flock and !have_flock_open_flags and flags.lock != .none) { | 4302 | if (have_flock and !have_flock_open_flags and options.lock != .none) { |
| 4302 | const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0; | 4303 | const lock_nonblocking: i32 = if (options.lock_nonblocking) posix.LOCK.NB else 0; |
| 4303 | const lock_flags = switch (flags.lock) { | 4304 | const lock_flags = switch (options.lock) { |
| 4304 | .none => unreachable, | 4305 | .none => unreachable, |
| 4305 | .shared => posix.LOCK.SH | lock_nonblocking, | 4306 | .shared => posix.LOCK.SH | lock_nonblocking, |
| 4306 | .exclusive => posix.LOCK.EX | lock_nonblocking, | 4307 | .exclusive => posix.LOCK.EX | lock_nonblocking, |
| ... | @@ -4332,7 +4333,7 @@ fn dirCreateFilePosix( | ... | @@ -4332,7 +4333,7 @@ fn dirCreateFilePosix( |
| 4332 | } | 4333 | } |
| 4333 | } | 4334 | } |
| 4334 | 4335 | ||
| 4335 | if (have_flock_open_flags and flags.lock_nonblocking) { | 4336 | if (have_flock_open_flags and options.lock_nonblocking) { |
| 4336 | var fl_flags: usize = fl: { | 4337 | var fl_flags: usize = fl: { |
| 4337 | const syscall: Syscall = try .start(); | 4338 | const syscall: Syscall = try .start(); |
| 4338 | while (true) { | 4339 | while (true) { |
| ... | @@ -4385,7 +4386,7 @@ fn dirCreateFileWindows( | ... | @@ -4385,7 +4386,7 @@ fn dirCreateFileWindows( |
| 4385 | userdata: ?*anyopaque, | 4386 | userdata: ?*anyopaque, |
| 4386 | dir: Dir, | 4387 | dir: Dir, |
| 4387 | sub_path: []const u8, | 4388 | sub_path: []const u8, |
| 4388 | flags: File.CreateFlags, | 4389 | flags: Dir.CreateFileOptions, |
| 4389 | ) File.OpenError!File { | 4390 | ) File.OpenError!File { |
| 4390 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4391 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4391 | _ = t; | 4392 | _ = t; |
| ... | @@ -4535,7 +4536,7 @@ fn dirCreateFileWasi( | ... | @@ -4535,7 +4536,7 @@ fn dirCreateFileWasi( |
| 4535 | userdata: ?*anyopaque, | 4536 | userdata: ?*anyopaque, |
| 4536 | dir: Dir, | 4537 | dir: Dir, |
| 4537 | sub_path: []const u8, | 4538 | sub_path: []const u8, |
| 4538 | flags: File.CreateFlags, | 4539 | flags: Dir.CreateFileOptions, |
| 4539 | ) File.OpenError!File { | 4540 | ) File.OpenError!File { |
| 4540 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4541 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4541 | _ = t; | 4542 | _ = t; |
| ... | @@ -4785,45 +4786,46 @@ fn dirOpenFilePosix( | ... | @@ -4785,45 +4786,46 @@ fn dirOpenFilePosix( |
| 4785 | userdata: ?*anyopaque, | 4786 | userdata: ?*anyopaque, |
| 4786 | dir: Dir, | 4787 | dir: Dir, |
| 4787 | sub_path: []const u8, | 4788 | sub_path: []const u8, |
| 4788 | flags: File.OpenFlags, | 4789 | options: Dir.OpenFileOptions, |
| 4789 | ) File.OpenError!File { | 4790 | ) File.OpenError!File { |
| 4790 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4791 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4791 | 4792 | ||
| 4792 | var path_buffer: [posix.PATH_MAX]u8 = undefined; | 4793 | var path_buffer: [posix.PATH_MAX]u8 = undefined; |
| 4793 | const sub_path_posix = try pathToPosix(sub_path, &path_buffer); | 4794 | const sub_path_posix = try pathToPosix(sub_path, &path_buffer); |
| 4794 | 4795 | ||
| 4795 | var os_flags: posix.O = switch (native_os) { | 4796 | var flags: posix.O = switch (native_os) { |
| 4796 | .wasi => .{ | 4797 | .wasi => .{ |
| 4797 | .read = flags.mode != .write_only, | 4798 | .read = options.mode != .write_only, |
| 4798 | .write = flags.mode != .read_only, | 4799 | .write = options.mode != .read_only, |
| 4799 | .NOFOLLOW = !flags.follow_symlinks, | 4800 | .NOFOLLOW = !options.follow_symlinks, |
| 4800 | }, | 4801 | }, |
| 4801 | else => .{ | 4802 | else => .{ |
| 4802 | .ACCMODE = switch (flags.mode) { | 4803 | .ACCMODE = switch (options.mode) { |
| 4803 | .read_only => .RDONLY, | 4804 | .read_only => .RDONLY, |
| 4804 | .write_only => .WRONLY, | 4805 | .write_only => .WRONLY, |
| 4805 | .read_write => .RDWR, | 4806 | .read_write => .RDWR, |
| 4806 | }, | 4807 | }, |
| 4807 | .NOFOLLOW = !flags.follow_symlinks, | 4808 | .NOFOLLOW = !options.follow_symlinks, |
| 4808 | }, | 4809 | }, |
| 4809 | }; | 4810 | }; |
| 4810 | if (@hasField(posix.O, "CLOEXEC")) os_flags.CLOEXEC = true; | 4811 | if (@hasField(posix.O, "CLOEXEC")) flags.CLOEXEC = true; |
| 4811 | if (@hasField(posix.O, "LARGEFILE")) os_flags.LARGEFILE = true; | 4812 | if (@hasField(posix.O, "LARGEFILE")) flags.LARGEFILE = true; |
| 4812 | if (@hasField(posix.O, "NOCTTY")) os_flags.NOCTTY = !flags.allow_ctty; | 4813 | if (@hasField(posix.O, "NOCTTY")) flags.NOCTTY = !options.allow_ctty; |
| 4813 | if (@hasField(posix.O, "PATH") and flags.path_only) os_flags.PATH = true; | 4814 | if (@hasField(posix.O, "PATH")) flags.PATH = options.path_only; |
| 4815 | if (@hasField(posix.O, "RESOLVE_BENEATH")) flags.RESOLVE_BENEATH = options.resolve_beneath; | ||
| 4814 | 4816 | ||
| 4815 | // Use the O locking flags if the os supports them to acquire the lock | 4817 | // Use the O locking options if the os supports them to acquire the lock |
| 4816 | // atomically. Note that the NONBLOCK flag is removed after the openat() | 4818 | // atomically. Note that the NONBLOCK flag is removed after the openat() |
| 4817 | // call is successful. | 4819 | // call is successful. |
| 4818 | if (have_flock_open_flags) switch (flags.lock) { | 4820 | if (have_flock_open_flags) switch (options.lock) { |
| 4819 | .none => {}, | 4821 | .none => {}, |
| 4820 | .shared => { | 4822 | .shared => { |
| 4821 | os_flags.SHLOCK = true; | 4823 | flags.SHLOCK = true; |
| 4822 | os_flags.NONBLOCK = flags.lock_nonblocking; | 4824 | flags.NONBLOCK = options.lock_nonblocking; |
| 4823 | }, | 4825 | }, |
| 4824 | .exclusive => { | 4826 | .exclusive => { |
| 4825 | os_flags.EXLOCK = true; | 4827 | flags.EXLOCK = true; |
| 4826 | os_flags.NONBLOCK = flags.lock_nonblocking; | 4828 | flags.NONBLOCK = options.lock_nonblocking; |
| 4827 | }, | 4829 | }, |
| 4828 | }; | 4830 | }; |
| 4829 | 4831 | ||
| ... | @@ -4832,7 +4834,7 @@ fn dirOpenFilePosix( | ... | @@ -4832,7 +4834,7 @@ fn dirOpenFilePosix( |
| 4832 | const fd: posix.fd_t = fd: { | 4834 | const fd: posix.fd_t = fd: { |
| 4833 | const syscall: Syscall = try .start(); | 4835 | const syscall: Syscall = try .start(); |
| 4834 | while (true) { | 4836 | while (true) { |
| 4835 | const rc = openat_sym(dir.handle, sub_path_posix, os_flags, mode); | 4837 | const rc = openat_sym(dir.handle, sub_path_posix, flags, mode); |
| 4836 | switch (posix.errno(rc)) { | 4838 | switch (posix.errno(rc)) { |
| 4837 | .SUCCESS => { | 4839 | .SUCCESS => { |
| 4838 | syscall.finish(); | 4840 | syscall.finish(); |
| ... | @@ -4878,7 +4880,7 @@ fn dirOpenFilePosix( | ... | @@ -4878,7 +4880,7 @@ fn dirOpenFilePosix( |
| 4878 | }; | 4880 | }; |
| 4879 | errdefer closeFd(fd); | 4881 | errdefer closeFd(fd); |
| 4880 | 4882 | ||
| 4881 | if (!flags.allow_directory) { | 4883 | if (!options.allow_directory) { |
| 4882 | const is_dir = is_dir: { | 4884 | const is_dir = is_dir: { |
| 4883 | const stat = fileStat(t, .{ | 4885 | const stat = fileStat(t, .{ |
| 4884 | .handle = fd, | 4886 | .handle = fd, |
| ... | @@ -4893,9 +4895,9 @@ fn dirOpenFilePosix( | ... | @@ -4893,9 +4895,9 @@ fn dirOpenFilePosix( |
| 4893 | if (is_dir) return error.IsDir; | 4895 | if (is_dir) return error.IsDir; |
| 4894 | } | 4896 | } |
| 4895 | 4897 | ||
| 4896 | if (have_flock and !have_flock_open_flags and flags.lock != .none) { | 4898 | if (have_flock and !have_flock_open_flags and options.lock != .none) { |
| 4897 | const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0; | 4899 | const lock_nonblocking: i32 = if (options.lock_nonblocking) posix.LOCK.NB else 0; |
| 4898 | const lock_flags = switch (flags.lock) { | 4900 | const lock_flags = switch (options.lock) { |
| 4899 | .none => unreachable, | 4901 | .none => unreachable, |
| 4900 | .shared => posix.LOCK.SH | lock_nonblocking, | 4902 | .shared => posix.LOCK.SH | lock_nonblocking, |
| 4901 | .exclusive => posix.LOCK.EX | lock_nonblocking, | 4903 | .exclusive => posix.LOCK.EX | lock_nonblocking, |
| ... | @@ -4926,7 +4928,7 @@ fn dirOpenFilePosix( | ... | @@ -4926,7 +4928,7 @@ fn dirOpenFilePosix( |
| 4926 | } | 4928 | } |
| 4927 | } | 4929 | } |
| 4928 | 4930 | ||
| 4929 | if (have_flock_open_flags and flags.lock_nonblocking) { | 4931 | if (have_flock_open_flags and options.lock_nonblocking) { |
| 4930 | var fl_flags: usize = fl: { | 4932 | var fl_flags: usize = fl: { |
| 4931 | const syscall: Syscall = try .start(); | 4933 | const syscall: Syscall = try .start(); |
| 4932 | while (true) { | 4934 | while (true) { |
| ... | @@ -4979,7 +4981,7 @@ fn dirOpenFileWindows( | ... | @@ -4979,7 +4981,7 @@ fn dirOpenFileWindows( |
| 4979 | userdata: ?*anyopaque, | 4981 | userdata: ?*anyopaque, |
| 4980 | dir: Dir, | 4982 | dir: Dir, |
| 4981 | sub_path: []const u8, | 4983 | sub_path: []const u8, |
| 4982 | flags: File.OpenFlags, | 4984 | flags: Dir.OpenFileOptions, |
| 4983 | ) File.OpenError!File { | 4985 | ) File.OpenError!File { |
| 4984 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4986 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4985 | _ = t; | 4987 | _ = t; |
| ... | @@ -4992,7 +4994,7 @@ fn dirOpenFileWindows( | ... | @@ -4992,7 +4994,7 @@ fn dirOpenFileWindows( |
| 4992 | pub fn dirOpenFileWtf16( | 4994 | pub fn dirOpenFileWtf16( |
| 4993 | dir_handle: ?windows.HANDLE, | 4995 | dir_handle: ?windows.HANDLE, |
| 4994 | sub_path_w: []const u16, | 4996 | sub_path_w: []const u16, |
| 4995 | flags: File.OpenFlags, | 4997 | flags: Dir.OpenFileOptions, |
| 4996 | ) File.OpenError!File { | 4998 | ) File.OpenError!File { |
| 4997 | const allow_directory = flags.allow_directory and !flags.isWrite(); | 4999 | const allow_directory = flags.allow_directory and !flags.isWrite(); |
| 4998 | if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir; | 5000 | if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir; |
| ... | @@ -5129,7 +5131,7 @@ fn dirOpenFileWasi( | ... | @@ -5129,7 +5131,7 @@ fn dirOpenFileWasi( |
| 5129 | userdata: ?*anyopaque, | 5131 | userdata: ?*anyopaque, |
| 5130 | dir: Dir, | 5132 | dir: Dir, |
| 5131 | sub_path: []const u8, | 5133 | sub_path: []const u8, |
| 5132 | flags: File.OpenFlags, | 5134 | flags: Dir.OpenFileOptions, |
| 5133 | ) File.OpenError!File { | 5135 | ) File.OpenError!File { |
| 5134 | if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags); | 5136 | if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags); |
| 5135 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 5137 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| ... | @@ -10193,7 +10195,7 @@ fn posixSeekTo(fd: posix.fd_t, offset: u64) File.SeekError!void { | ... | @@ -10193,7 +10195,7 @@ fn posixSeekTo(fd: posix.fd_t, offset: u64) File.SeekError!void { |
| 10193 | } | 10195 | } |
| 10194 | } | 10196 | } |
| 10195 | 10197 | ||
| 10196 | fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) process.OpenExecutableError!File { | 10198 | fn processExecutableOpen(userdata: ?*anyopaque, flags: Dir.OpenFileOptions) process.OpenExecutableError!File { |
| 10197 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 10199 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 10198 | switch (native_os) { | 10200 | switch (native_os) { |
| 10199 | .wasi => return error.OperationUnsupported, | 10201 | .wasi => return error.OperationUnsupported, |
lib/std/c.zig+2-1| ... | @@ -8535,7 +8535,8 @@ pub const O = switch (native_os) { | ... | @@ -8535,7 +8535,8 @@ pub const O = switch (native_os) { |
| 8535 | CREAT: bool = false, | 8535 | CREAT: bool = false, |
| 8536 | TRUNC: bool = false, | 8536 | TRUNC: bool = false, |
| 8537 | EXCL: bool = false, | 8537 | EXCL: bool = false, |
| 8538 | _12: u3 = 0, | 8538 | RESOLVE_BENEATH: bool = false, |
| 8539 | _13: u2 = 0, | ||
| 8539 | EVTONLY: bool = false, | 8540 | EVTONLY: bool = false, |
| 8540 | _16: u1 = 0, | 8541 | _16: u1 = 0, |
| 8541 | NOCTTY: bool = false, | 8542 | NOCTTY: bool = false, |