| author | |
| committer | |
| log | b561d5f3feda6b1251fc2b8ab2430e78f546577c |
| tree | 4f4a289296f8dda8f52aa62b5892905df7df09f5 |
| parent | aa6e8eff40bdf35c838c8cd93080f2e9d4fad3b2 |
5 files changed, 59 insertions(+), 64 deletions(-)
lib/std/Io/Dir.zig+7| ... | ... | @@ -101,6 +101,13 @@ pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) F |
| 101 | 101 | return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags); |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | /// Creates, opens, or overwrites a file with write access. | |
| 105 | /// | |
| 106 | /// Allocates a resource to be dellocated with `File.close`. | |
| 107 | /// | |
| 108 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | |
| 109 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | |
| 110 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | |
| 104 | 111 | pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { |
| 105 | 112 | return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags); |
| 106 | 113 | } |
lib/std/Io/Threaded.zig+49-1| ... | ... | @@ -187,7 +187,7 @@ pub fn io(t: *Threaded) Io { |
| 187 | 187 | else => dirAccessPosix, |
| 188 | 188 | }, |
| 189 | 189 | .dirCreateFile = switch (builtin.os.tag) { |
| 190 | .windows => @panic("TODO"), | |
| 190 | .windows => dirCreateFileWindows, | |
| 191 | 191 | .wasi => dirCreateFileWasi, |
| 192 | 192 | else => dirCreateFilePosix, |
| 193 | 193 | }, |
| ... | ... | @@ -1483,6 +1483,54 @@ fn dirCreateFilePosix( |
| 1483 | 1483 | return .{ .handle = fd }; |
| 1484 | 1484 | } |
| 1485 | 1485 | |
| 1486 | fn dirCreateFileWindows( | |
| 1487 | userdata: ?*anyopaque, | |
| 1488 | dir: Io.Dir, | |
| 1489 | sub_path: []const u8, | |
| 1490 | flags: Io.File.CreateFlags, | |
| 1491 | ) Io.File.OpenError!Io.File { | |
| 1492 | const w = windows; | |
| 1493 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 1494 | try t.checkCancel(); | |
| 1495 | ||
| 1496 | const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path); | |
| 1497 | const sub_path_w = sub_path_w_array.span(); | |
| 1498 | ||
| 1499 | const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0; | |
| 1500 | const handle = try w.OpenFile(sub_path_w, .{ | |
| 1501 | .dir = dir.handle, | |
| 1502 | .access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag, | |
| 1503 | .creation = if (flags.exclusive) | |
| 1504 | @as(u32, w.FILE_CREATE) | |
| 1505 | else if (flags.truncate) | |
| 1506 | @as(u32, w.FILE_OVERWRITE_IF) | |
| 1507 | else | |
| 1508 | @as(u32, w.FILE_OPEN_IF), | |
| 1509 | }); | |
| 1510 | errdefer w.CloseHandle(handle); | |
| 1511 | var io_status_block: w.IO_STATUS_BLOCK = undefined; | |
| 1512 | const range_off: w.LARGE_INTEGER = 0; | |
| 1513 | const range_len: w.LARGE_INTEGER = 1; | |
| 1514 | const exclusive = switch (flags.lock) { | |
| 1515 | .none => return .{ .handle = handle }, | |
| 1516 | .shared => false, | |
| 1517 | .exclusive => true, | |
| 1518 | }; | |
| 1519 | try w.LockFile( | |
| 1520 | handle, | |
| 1521 | null, | |
| 1522 | null, | |
| 1523 | null, | |
| 1524 | &io_status_block, | |
| 1525 | &range_off, | |
| 1526 | &range_len, | |
| 1527 | null, | |
| 1528 | @intFromBool(flags.lock_nonblocking), | |
| 1529 | @intFromBool(exclusive), | |
| 1530 | ); | |
| 1531 | return .{ .handle = handle }; | |
| 1532 | } | |
| 1533 | ||
| 1486 | 1534 | fn dirCreateFileWasi( |
| 1487 | 1535 | userdata: ?*anyopaque, |
| 1488 | 1536 | dir: Io.Dir, |
lib/std/fs.zig-6| ... | ... | @@ -299,12 +299,6 @@ pub fn createFileAbsolute(absolute_path: []const u8, flags: File.CreateFlags) Fi |
| 299 | 299 | return cwd().createFile(absolute_path, flags); |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | /// Same as `createFileAbsolute` but the path parameter is WTF-16 encoded. | |
| 303 | pub fn createFileAbsoluteW(absolute_path_w: [*:0]const u16, flags: File.CreateFlags) File.OpenError!File { | |
| 304 | assert(path.isAbsoluteWindowsW(absolute_path_w)); | |
| 305 | return cwd().createFileW(mem.span(absolute_path_w), flags); | |
| 306 | } | |
| 307 | ||
| 308 | 302 | /// Delete a file name and possibly the file it refers to, based on an absolute path. |
| 309 | 303 | /// Asserts that the path is absolute. See `Dir.deleteFile` for a function that |
| 310 | 304 | /// operates on both absolute and relative paths. |
lib/std/fs/Dir.zig+1-51| ... | ... | @@ -900,64 +900,14 @@ pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File |
| 900 | 900 | return file; |
| 901 | 901 | } |
| 902 | 902 | |
| 903 | /// Creates, opens, or overwrites a file with write access. | |
| 904 | /// Call `File.close` on the result when done. | |
| 905 | /// Asserts that the path parameter has no null bytes. | |
| 906 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | |
| 907 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | |
| 908 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | |
| 903 | /// Deprecated in favor of `Io.Dir.createFile`. | |
| 909 | 904 | pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { |
| 910 | if (native_os == .windows) { | |
| 911 | const path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path); | |
| 912 | return self.createFileW(path_w.span(), flags); | |
| 913 | } | |
| 914 | 905 | var threaded: Io.Threaded = .init_single_threaded; |
| 915 | 906 | const io = threaded.io(); |
| 916 | 907 | const new_file = try Io.Dir.createFile(self.adaptToNewApi(), io, sub_path, flags); |
| 917 | 908 | return .adaptFromNewApi(new_file); |
| 918 | 909 | } |
| 919 | 910 | |
| 920 | /// Same as `createFile` but Windows-only and the path parameter is | |
| 921 | /// [WTF-16](https://wtf-8.codeberg.page/#potentially-ill-formed-utf-16) encoded. | |
| 922 | pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) File.OpenError!File { | |
| 923 | const w = windows; | |
| 924 | const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0; | |
| 925 | const file: File = .{ | |
| 926 | .handle = try w.OpenFile(sub_path_w, .{ | |
| 927 | .dir = self.fd, | |
| 928 | .access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag, | |
| 929 | .creation = if (flags.exclusive) | |
| 930 | @as(u32, w.FILE_CREATE) | |
| 931 | else if (flags.truncate) | |
| 932 | @as(u32, w.FILE_OVERWRITE_IF) | |
| 933 | else | |
| 934 | @as(u32, w.FILE_OPEN_IF), | |
| 935 | }), | |
| 936 | }; | |
| 937 | errdefer file.close(); | |
| 938 | var io: w.IO_STATUS_BLOCK = undefined; | |
| 939 | const range_off: w.LARGE_INTEGER = 0; | |
| 940 | const range_len: w.LARGE_INTEGER = 1; | |
| 941 | const exclusive = switch (flags.lock) { | |
| 942 | .none => return file, | |
| 943 | .shared => false, | |
| 944 | .exclusive => true, | |
| 945 | }; | |
| 946 | try w.LockFile( | |
| 947 | file.handle, | |
| 948 | null, | |
| 949 | null, | |
| 950 | null, | |
| 951 | &io, | |
| 952 | &range_off, | |
| 953 | &range_len, | |
| 954 | null, | |
| 955 | @intFromBool(flags.lock_nonblocking), | |
| 956 | @intFromBool(exclusive), | |
| 957 | ); | |
| 958 | return file; | |
| 959 | } | |
| 960 | ||
| 961 | 911 | /// Deprecated in favor of `Io.Dir.MakeError`. |
| 962 | 912 | pub const MakeError = Io.Dir.MakeError; |
| 963 | 913 |
lib/std/posix.zig+2-6| ... | ... | @@ -4684,9 +4684,7 @@ pub const AccessError = error{ |
| 4684 | 4684 | /// Windows. See `fs` for the cross-platform file system API. |
| 4685 | 4685 | pub fn access(path: []const u8, mode: u32) AccessError!void { |
| 4686 | 4686 | if (native_os == .windows) { |
| 4687 | const path_w = try windows.sliceToPrefixedFileW(null, path); | |
| 4688 | _ = try windows.GetFileAttributesW(path_w.span().ptr); | |
| 4689 | return; | |
| 4687 | @compileError("use std.Io instead"); | |
| 4690 | 4688 | } else if (native_os == .wasi and !builtin.link_libc) { |
| 4691 | 4689 | @compileError("wasi doesn't support absolute paths"); |
| 4692 | 4690 | } |
| ... | ... | @@ -4697,9 +4695,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void { |
| 4697 | 4695 | /// Same as `access` except `path` is null-terminated. |
| 4698 | 4696 | pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void { |
| 4699 | 4697 | if (native_os == .windows) { |
| 4700 | const path_w = try windows.cStrToPrefixedFileW(null, path); | |
| 4701 | _ = try windows.GetFileAttributesW(path_w.span().ptr); | |
| 4702 | return; | |
| 4698 | @compileError("use std.Io instead"); | |
| 4703 | 4699 | } else if (native_os == .wasi and !builtin.link_libc) { |
| 4704 | 4700 | return access(mem.sliceTo(path, 0), mode); |
| 4705 | 4701 | } |