authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-02 01:25:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-02 01:25:22-04:00
log43f7856bac5fd1a93970d7cebd20289de2367691
treec3fe6d202185d677b983ef0ff205538188dfe55f
parent2272a07ca0661547a6889aa7f1b6262fef5dad85

fix regressions in windows std lib tests


4 files changed, 85 insertions(+), 112 deletions(-)

lib/std/dynamic_library.zig+2-2
......@@ -328,14 +328,14 @@ pub const WindowsDynLib = struct {
328328
329329 pub fn open(path: []const u8) !WindowsDynLib {
330330 const path_w = try windows.sliceToPrefixedFileW(path);
331 return openW(&path_w);
331 return openW(path_w.span().ptr);
332332 }
333333
334334 pub const openC = @compileError("deprecated: renamed to openZ");
335335
336336 pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib {
337337 const path_w = try windows.cStrToPrefixedFileW(path_c);
338 return openW(&path_w);
338 return openW(path_w.span().ptr);
339339 }
340340
341341 pub fn openW(path_w: [*:0]const u16) !WindowsDynLib {
lib/std/fs.zig+11-11
......@@ -199,7 +199,7 @@ pub const AtomicFile = struct {
199199 if (std.Target.current.os.tag == .windows) {
200200 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_basename);
201201 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);
202 try os.renameatW(self.dir.fd, &tmp_path_w, self.dir.fd, &dest_path_w, os.windows.TRUE);
202 try os.renameatW(self.dir.fd, tmp_path_w.span(), self.dir.fd, dest_path_w.span(), os.windows.TRUE);
203203 self.file_exists = false;
204204 } else {
205205 const dest_path_c = try os.toPosixPath(self.dest_basename);
......@@ -582,7 +582,7 @@ pub const Dir = struct {
582582 pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
583583 if (builtin.os.tag == .windows) {
584584 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
585 return self.openFileW(&path_w, flags);
585 return self.openFileW(path_w.span(), flags);
586586 }
587587 const path_c = try os.toPosixPath(sub_path);
588588 return self.openFileZ(&path_c, flags);
......@@ -594,7 +594,7 @@ pub const Dir = struct {
594594 pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
595595 if (builtin.os.tag == .windows) {
596596 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
597 return self.openFileW(&path_w, flags);
597 return self.openFileW(path_w.span(), flags);
598598 }
599599
600600 // Use the O_ locking flags if the os supports them
......@@ -669,7 +669,7 @@ pub const Dir = struct {
669669 pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
670670 if (builtin.os.tag == .windows) {
671671 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
672 return self.createFileW(&path_w, flags);
672 return self.createFileW(path_w.span(), flags);
673673 }
674674 const path_c = try os.toPosixPath(sub_path);
675675 return self.createFileZ(&path_c, flags);
......@@ -681,7 +681,7 @@ pub const Dir = struct {
681681 pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
682682 if (builtin.os.tag == .windows) {
683683 const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
684 return self.createFileW(&path_w, flags);
684 return self.createFileW(path_w.span(), flags);
685685 }
686686
687687 // Use the O_ locking flags if the os supports them
......@@ -832,7 +832,7 @@ pub const Dir = struct {
832832 pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {
833833 if (builtin.os.tag == .windows) {
834834 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
835 return self.openDirW(&sub_path_w, args);
835 return self.openDirW(sub_path_w.span().ptr, args);
836836 } else {
837837 const sub_path_c = try os.toPosixPath(sub_path);
838838 return self.openDirZ(&sub_path_c, args);
......@@ -845,7 +845,7 @@ pub const Dir = struct {
845845 pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) OpenError!Dir {
846846 if (builtin.os.tag == .windows) {
847847 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
848 return self.openDirW(&sub_path_w, args);
848 return self.openDirW(sub_path_w.span().ptr, args);
849849 } else if (!args.iterate) {
850850 const O_PATH = if (@hasDecl(os, "O_PATH")) os.O_PATH else 0;
851851 return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | O_PATH);
......@@ -987,7 +987,7 @@ pub const Dir = struct {
987987 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {
988988 if (builtin.os.tag == .windows) {
989989 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
990 return self.deleteDirW(&sub_path_w);
990 return self.deleteDirW(sub_path_w.span().ptr);
991991 }
992992 const sub_path_c = try os.toPosixPath(sub_path);
993993 return self.deleteDirZ(&sub_path_c);
......@@ -1246,7 +1246,7 @@ pub const Dir = struct {
12461246 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {
12471247 if (builtin.os.tag == .windows) {
12481248 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
1249 return self.accessW(&sub_path_w, flags);
1249 return self.accessW(sub_path_w.span().ptr, flags);
12501250 }
12511251 const path_c = try os.toPosixPath(sub_path);
12521252 return self.accessZ(&path_c, flags);
......@@ -1256,7 +1256,7 @@ pub const Dir = struct {
12561256 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {
12571257 if (builtin.os.tag == .windows) {
12581258 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path);
1259 return self.accessW(&sub_path_w, flags);
1259 return self.accessW(sub_path_w.span().ptr, flags);
12601260 }
12611261 const os_mode = if (flags.write and flags.read)
12621262 @as(u32, os.R_OK | os.W_OK)
......@@ -1596,7 +1596,7 @@ pub fn openSelfExe() OpenSelfExeError!File {
15961596 if (builtin.os.tag == .windows) {
15971597 const wide_slice = selfExePathW();
15981598 const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);
1599 return cwd().openFileW(&prefixed_path_w, .{});
1599 return cwd().openFileW(prefixed_path_w.span(), .{});
16001600 }
16011601 var buf: [MAX_PATH_BYTES]u8 = undefined;
16021602 const self_exe_path = try selfExePath(&buf);
lib/std/os.zig+23-23
......@@ -857,7 +857,7 @@ pub const OpenError = error{
857857pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t {
858858 if (std.Target.current.os.tag == .windows) {
859859 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
860 return openW(&file_path_w, flags, perm);
860 return openW(file_path_w.span(), flags, perm);
861861 }
862862 const file_path_c = try toPosixPath(file_path);
863863 return openZ(&file_path_c, flags, perm);
......@@ -870,7 +870,7 @@ pub const openC = @compileError("deprecated: renamed to openZ");
870870pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t {
871871 if (std.Target.current.os.tag == .windows) {
872872 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
873 return openW(&file_path_w, flags, perm);
873 return openW(file_path_w.span(), flags, perm);
874874 }
875875 while (true) {
876876 const rc = system.open(file_path, flags, perm);
......@@ -1317,7 +1317,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
13171317 if (builtin.os.tag == .windows) {
13181318 const target_path_w = try windows.sliceToPrefixedFileW(target_path);
13191319 const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
1320 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
1320 return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0);
13211321 } else {
13221322 const target_path_c = try toPosixPath(target_path);
13231323 const sym_link_path_c = try toPosixPath(sym_link_path);
......@@ -1333,7 +1333,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
13331333 if (builtin.os.tag == .windows) {
13341334 const target_path_w = try windows.cStrToPrefixedFileW(target_path);
13351335 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
1336 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
1336 return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0);
13371337 }
13381338 switch (errno(system.symlink(target_path, sym_link_path))) {
13391339 0 => return,
......@@ -1409,7 +1409,7 @@ pub const UnlinkError = error{
14091409pub fn unlink(file_path: []const u8) UnlinkError!void {
14101410 if (builtin.os.tag == .windows) {
14111411 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
1412 return windows.DeleteFileW(&file_path_w);
1412 return windows.DeleteFileW(file_path_w.span().ptr);
14131413 } else {
14141414 const file_path_c = try toPosixPath(file_path);
14151415 return unlinkZ(&file_path_c);
......@@ -1422,7 +1422,7 @@ pub const unlinkC = @compileError("deprecated: renamed to unlinkZ");
14221422pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
14231423 if (builtin.os.tag == .windows) {
14241424 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1425 return windows.DeleteFileW(&file_path_w);
1425 return windows.DeleteFileW(file_path_w.span().ptr);
14261426 }
14271427 switch (errno(system.unlink(file_path))) {
14281428 0 => return,
......@@ -1453,7 +1453,7 @@ pub const UnlinkatError = UnlinkError || error{
14531453pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
14541454 if (builtin.os.tag == .windows) {
14551455 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
1456 return unlinkatW(dirfd, &file_path_w, flags);
1456 return unlinkatW(dirfd, file_path_w.span().ptr, flags);
14571457 }
14581458 const file_path_c = try toPosixPath(file_path);
14591459 return unlinkatZ(dirfd, &file_path_c, flags);
......@@ -1465,7 +1465,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");
14651465pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {
14661466 if (builtin.os.tag == .windows) {
14671467 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);
1468 return unlinkatW(dirfd, &file_path_w, flags);
1468 return unlinkatW(dirfd, file_path_w.span().ptr, flags);
14691469 }
14701470 switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {
14711471 0 => return,
......@@ -1580,7 +1580,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
15801580 if (builtin.os.tag == .windows) {
15811581 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
15821582 const new_path_w = try windows.sliceToPrefixedFileW(new_path);
1583 return renameW(&old_path_w, &new_path_w);
1583 return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
15841584 } else {
15851585 const old_path_c = try toPosixPath(old_path);
15861586 const new_path_c = try toPosixPath(new_path);
......@@ -1595,7 +1595,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi
15951595 if (builtin.os.tag == .windows) {
15961596 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
15971597 const new_path_w = try windows.cStrToPrefixedFileW(new_path);
1598 return renameW(&old_path_w, &new_path_w);
1598 return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
15991599 }
16001600 switch (errno(system.rename(old_path, new_path))) {
16011601 0 => return,
......@@ -1638,7 +1638,7 @@ pub fn renameat(
16381638 if (builtin.os.tag == .windows) {
16391639 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
16401640 const new_path_w = try windows.sliceToPrefixedFileW(new_path);
1641 return renameatW(old_dir_fd, &old_path_w, new_dir_fd, &new_path_w, windows.TRUE);
1641 return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
16421642 } else {
16431643 const old_path_c = try toPosixPath(old_path);
16441644 const new_path_c = try toPosixPath(new_path);
......@@ -1656,7 +1656,7 @@ pub fn renameatZ(
16561656 if (builtin.os.tag == .windows) {
16571657 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
16581658 const new_path_w = try windows.cStrToPrefixedFileW(new_path);
1659 return renameatW(old_dir_fd, &old_path_w, new_dir_fd, &new_path_w, windows.TRUE);
1659 return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
16601660 }
16611661
16621662 switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {
......@@ -1760,7 +1760,7 @@ pub const MakeDirError = error{
17601760pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
17611761 if (builtin.os.tag == .windows) {
17621762 const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path);
1763 return mkdiratW(dir_fd, &sub_dir_path_w, mode);
1763 return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode);
17641764 } else {
17651765 const sub_dir_path_c = try toPosixPath(sub_dir_path);
17661766 return mkdiratZ(dir_fd, &sub_dir_path_c, mode);
......@@ -1772,7 +1772,7 @@ pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ");
17721772pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
17731773 if (builtin.os.tag == .windows) {
17741774 const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path);
1775 return mkdiratW(dir_fd, &sub_dir_path_w, mode);
1775 return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode);
17761776 }
17771777 switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {
17781778 0 => return,
......@@ -1816,7 +1816,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
18161816pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
18171817 if (builtin.os.tag == .windows) {
18181818 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1819 const sub_dir_handle = try windows.CreateDirectoryW(null, &dir_path_w, null);
1819 const sub_dir_handle = try windows.CreateDirectoryW(null, dir_path_w.span().ptr, null);
18201820 windows.CloseHandle(sub_dir_handle);
18211821 return;
18221822 }
......@@ -1857,7 +1857,7 @@ pub const DeleteDirError = error{
18571857pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
18581858 if (builtin.os.tag == .windows) {
18591859 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
1860 return windows.RemoveDirectoryW(&dir_path_w);
1860 return windows.RemoveDirectoryW(dir_path_w.span().ptr);
18611861 } else {
18621862 const dir_path_c = try toPosixPath(dir_path);
18631863 return rmdirZ(&dir_path_c);
......@@ -1870,7 +1870,7 @@ pub const rmdirC = @compileError("deprecated: renamed to rmdirZ");
18701870pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
18711871 if (builtin.os.tag == .windows) {
18721872 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1873 return windows.RemoveDirectoryW(&dir_path_w);
1873 return windows.RemoveDirectoryW(dir_path_w.span().ptr);
18741874 }
18751875 switch (errno(system.rmdir(dir_path))) {
18761876 0 => return,
......@@ -2880,7 +2880,7 @@ pub const AccessError = error{
28802880pub fn access(path: []const u8, mode: u32) AccessError!void {
28812881 if (builtin.os.tag == .windows) {
28822882 const path_w = try windows.sliceToPrefixedFileW(path);
2883 _ = try windows.GetFileAttributesW(&path_w);
2883 _ = try windows.GetFileAttributesW(path_w.span().ptr);
28842884 return;
28852885 }
28862886 const path_c = try toPosixPath(path);
......@@ -2893,7 +2893,7 @@ pub const accessC = @compileError("Deprecated in favor of `accessZ`");
28932893pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
28942894 if (builtin.os.tag == .windows) {
28952895 const path_w = try windows.cStrToPrefixedFileW(path);
2896 _ = try windows.GetFileAttributesW(&path_w);
2896 _ = try windows.GetFileAttributesW(path_w.span().ptr);
28972897 return;
28982898 }
28992899 switch (errno(system.access(path, mode))) {
......@@ -2934,7 +2934,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v
29342934pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
29352935 if (builtin.os.tag == .windows) {
29362936 const path_w = try windows.sliceToPrefixedFileW(path);
2937 return faccessatW(dirfd, &path_w, mode, flags);
2937 return faccessatW(dirfd, path_w.span().ptr, mode, flags);
29382938 }
29392939 const path_c = try toPosixPath(path);
29402940 return faccessatZ(dirfd, &path_c, mode, flags);
......@@ -2944,7 +2944,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr
29442944pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
29452945 if (builtin.os.tag == .windows) {
29462946 const path_w = try windows.cStrToPrefixedFileW(path);
2947 return faccessatW(dirfd, &path_w, mode, flags);
2947 return faccessatW(dirfd, path_w.span().ptr, mode, flags);
29482948 }
29492949 switch (errno(system.faccessat(dirfd, path, mode, flags))) {
29502950 0 => return,
......@@ -3299,7 +3299,7 @@ pub const RealPathError = error{
32993299pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
33003300 if (builtin.os.tag == .windows) {
33013301 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
3302 return realpathW(&pathname_w, out_buffer);
3302 return realpathW(pathname_w.span().ptr, out_buffer);
33033303 }
33043304 const pathname_c = try toPosixPath(pathname);
33053305 return realpathZ(&pathname_c, out_buffer);
......@@ -3311,7 +3311,7 @@ pub const realpathC = @compileError("deprecated: renamed realpathZ");
33113311pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
33123312 if (builtin.os.tag == .windows) {
33133313 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
3314 return realpathW(&pathname_w, out_buffer);
3314 return realpathW(pathname_w.span().ptr, out_buffer);
33153315 }
33163316 if (builtin.os.tag == .linux and !builtin.link_libc) {
33173317 const fd = openZ(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0) catch |err| switch (err) {
lib/std/os/windows.zig+49-76
......@@ -59,7 +59,7 @@ pub fn CreateFile(
5959 hTemplateFile: ?HANDLE,
6060) CreateFileError!HANDLE {
6161 const file_path_w = try sliceToPrefixedFileW(file_path);
62 return CreateFileW(&file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
62 return CreateFileW(file_path_w.span().ptr, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
6363}
6464
6565pub fn CreateFileW(
......@@ -116,10 +116,10 @@ pub const OpenFileOptions = struct {
116116/// TODO when share_access_nonblocking is false, this implementation uses
117117/// untinterruptible sleep() to block. This is not the final iteration of the API.
118118pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HANDLE {
119 if (mem.eql(u16, sub_path_w, ".")) {
119 if (mem.eql(u16, sub_path_w, &[_]u16{'.'})) {
120120 return error.IsDir;
121121 }
122 if (mem.eql(u16, sub_path_w, "..")) {
122 if (mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' })) {
123123 return error.IsDir;
124124 }
125125
......@@ -199,7 +199,7 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
199199
200200pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE {
201201 const nameW = try sliceToPrefixedFileW(name);
202 return CreateEventExW(attributes, &nameW, flags, desired_access);
202 return CreateEventExW(attributes, nameW.span().ptr, flags, desired_access);
203203}
204204
205205pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE {
......@@ -332,42 +332,6 @@ pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, millisec
332332 }
333333}
334334
335pub const FindFirstFileError = error{
336 FileNotFound,
337 InvalidUtf8,
338 BadPathName,
339 NameTooLong,
340 Unexpected,
341};
342
343pub fn FindFirstFile(dir_path: []const u8, find_file_data: *WIN32_FIND_DATAW) FindFirstFileError!HANDLE {
344 const dir_path_w = try sliceToPrefixedSuffixedFileW(dir_path, [_]u16{ '\\', '*' });
345 const handle = kernel32.FindFirstFileW(&dir_path_w, find_file_data);
346
347 if (handle == INVALID_HANDLE_VALUE) {
348 switch (kernel32.GetLastError()) {
349 .FILE_NOT_FOUND => return error.FileNotFound,
350 .PATH_NOT_FOUND => return error.FileNotFound,
351 else => |err| return unexpectedError(err),
352 }
353 }
354
355 return handle;
356}
357
358pub const FindNextFileError = error{Unexpected};
359
360/// Returns `true` if there was another file, `false` otherwise.
361pub fn FindNextFile(handle: HANDLE, find_file_data: *WIN32_FIND_DATAW) FindNextFileError!bool {
362 if (kernel32.FindNextFileW(handle, find_file_data) == 0) {
363 switch (kernel32.GetLastError()) {
364 .NO_MORE_FILES => return false,
365 else => |err| return unexpectedError(err),
366 }
367 }
368 return true;
369}
370
371335pub const CreateIoCompletionPortError = error{Unexpected};
372336
373337pub fn CreateIoCompletionPort(
......@@ -644,7 +608,7 @@ pub fn CreateSymbolicLink(
644608) CreateSymbolicLinkError!void {
645609 const sym_link_path_w = try sliceToPrefixedFileW(sym_link_path);
646610 const target_path_w = try sliceToPrefixedFileW(target_path);
647 return CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, flags);
611 return CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, flags);
648612}
649613
650614pub fn CreateSymbolicLinkW(
......@@ -669,7 +633,7 @@ pub const DeleteFileError = error{
669633
670634pub fn DeleteFile(filename: []const u8) DeleteFileError!void {
671635 const filename_w = try sliceToPrefixedFileW(filename);
672 return DeleteFileW(&filename_w);
636 return DeleteFileW(filename_w.span().ptr);
673637}
674638
675639pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void {
......@@ -691,7 +655,7 @@ pub const MoveFileError = error{Unexpected};
691655pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) MoveFileError!void {
692656 const old_path_w = try sliceToPrefixedFileW(old_path);
693657 const new_path_w = try sliceToPrefixedFileW(new_path);
694 return MoveFileExW(&old_path_w, &new_path_w, flags);
658 return MoveFileExW(old_path_w.span().ptr, new_path_w.span().ptr, flags);
695659}
696660
697661pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void {
......@@ -716,7 +680,7 @@ pub const CreateDirectoryError = error{
716680/// Returns an open directory handle which the caller is responsible for closing with `CloseHandle`.
717681pub fn CreateDirectory(dir: ?HANDLE, pathname: []const u8, sa: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!HANDLE {
718682 const pathname_w = try sliceToPrefixedFileW(pathname);
719 return CreateDirectoryW(dir, &pathname_w, sa);
683 return CreateDirectoryW(dir, pathname_w.span().ptr, sa);
720684}
721685
722686/// Same as `CreateDirectory` except takes a WTF-16 encoded path.
......@@ -784,7 +748,7 @@ pub const RemoveDirectoryError = error{
784748
785749pub fn RemoveDirectory(dir_path: []const u8) RemoveDirectoryError!void {
786750 const dir_path_w = try sliceToPrefixedFileW(dir_path);
787 return RemoveDirectoryW(&dir_path_w);
751 return RemoveDirectoryW(dir_path_w.span().ptr);
788752}
789753
790754pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void {
......@@ -913,7 +877,7 @@ pub const GetFileAttributesError = error{
913877
914878pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {
915879 const filename_w = try sliceToPrefixedFileW(filename);
916 return GetFileAttributesW(&filename_w);
880 return GetFileAttributesW(filename_w.span().ptr);
917881}
918882
919883pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD {
......@@ -1253,34 +1217,22 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME {
12531217 };
12541218}
12551219
1256pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 {
1257 return sliceToPrefixedFileW(mem.spanZ(s));
1258}
1259
1260pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE:0]u16 {
1261 return sliceToPrefixedSuffixedFileW(s, &[_]u16{});
1262}
1220pub const PathSpace = struct {
1221 data: [PATH_MAX_WIDE:0]u16,
1222 len: usize,
12631223
1264/// Assumes an absolute path.
1265pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 {
1266 // TODO https://github.com/ziglang/zig/issues/2765
1267 var result: [PATH_MAX_WIDE:0]u16 = undefined;
1224 pub fn span(self: PathSpace) [:0]const u16 {
1225 return self.data[0..self.len :0];
1226 }
1227};
12681228
1269 const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: {
1270 const prefix = [_]u16{ '\\', '?', '?', '\\' };
1271 mem.copy(u16, result[0..], &prefix);
1272 break :blk prefix.len;
1273 };
1274 const end_index = start_index + s.len;
1275 if (end_index + 1 > result.len) return error.NameTooLong;
1276 mem.copy(u16, result[start_index..], s);
1277 result[end_index] = 0;
1278 return result;
1229pub fn cStrToPrefixedFileW(s: [*:0]const u8) !PathSpace {
1230 return sliceToPrefixedFileW(mem.spanZ(s));
12791231}
12801232
1281pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len:0]u16 {
1233pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
12821234 // TODO https://github.com/ziglang/zig/issues/2765
1283 var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined;
1235 var path_space: PathSpace = undefined;
12841236 for (s) |byte| {
12851237 switch (byte) {
12861238 '*', '?', '"', '<', '>', '|' => return error.BadPathName,
......@@ -1289,25 +1241,46 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
12891241 }
12901242 const start_index = if (mem.startsWith(u8, s, "\\?") or !std.fs.path.isAbsolute(s)) 0 else blk: {
12911243 const prefix = [_]u16{ '\\', '?', '?', '\\' };
1292 mem.copy(u16, result[0..], &prefix);
1244 mem.copy(u16, path_space.data[0..], &prefix);
12931245 break :blk prefix.len;
12941246 };
1295 const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);
1296 if (end_index + suffix.len > result.len) return error.NameTooLong;
1247 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
1248 if (path_space.len > path_space.data.len) return error.NameTooLong;
12971249 // > File I/O functions in the Windows API convert "/" to "\" as part of
12981250 // > converting the name to an NT-style name, except when using the "\\?\"
12991251 // > prefix as detailed in the following sections.
13001252 // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
13011253 // Because we want the larger maximum path length for absolute paths, we
13021254 // convert forward slashes to backward slashes here.
1303 for (result[0..end_index]) |*elem| {
1255 for (path_space.data[0..path_space.len]) |*elem| {
13041256 if (elem.* == '/') {
13051257 elem.* = '\\';
13061258 }
13071259 }
1308 mem.copy(u16, result[end_index..], suffix);
1309 result[end_index + suffix.len] = 0;
1310 return result;
1260 path_space.data[path_space.len] = 0;
1261 return path_space;
1262}
1263
1264/// Assumes an absolute path.
1265pub fn wToPrefixedFileW(s: []const u16) !PathSpace {
1266 // TODO https://github.com/ziglang/zig/issues/2765
1267 var path_space: PathSpace = undefined;
1268
1269 const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: {
1270 const prefix = [_]u16{ '\\', '?', '?', '\\' };
1271 mem.copy(u16, path_space.data[0..], &prefix);
1272 break :blk prefix.len;
1273 };
1274 path_space.len = start_index + s.len;
1275 if (path_space.len > path_space.data.len) return error.NameTooLong;
1276 mem.copy(u16, path_space.data[start_index..], s);
1277 for (path_space.data[0..path_space.len]) |*elem| {
1278 if (elem.* == '/') {
1279 elem.* = '\\';
1280 }
1281 }
1282 path_space.data[path_space.len] = 0;
1283 return path_space;
13111284}
13121285
13131286inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {