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 {...@@ -328,14 +328,14 @@ pub const WindowsDynLib = struct {
328328
329 pub fn open(path: []const u8) !WindowsDynLib {329 pub fn open(path: []const u8) !WindowsDynLib {
330 const path_w = try windows.sliceToPrefixedFileW(path);330 const path_w = try windows.sliceToPrefixedFileW(path);
331 return openW(&path_w);331 return openW(path_w.span().ptr);
332 }332 }
333333
334 pub const openC = @compileError("deprecated: renamed to openZ");334 pub const openC = @compileError("deprecated: renamed to openZ");
335335
336 pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib {336 pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib {
337 const path_w = try windows.cStrToPrefixedFileW(path_c);337 const path_w = try windows.cStrToPrefixedFileW(path_c);
338 return openW(&path_w);338 return openW(path_w.span().ptr);
339 }339 }
340340
341 pub fn openW(path_w: [*:0]const u16) !WindowsDynLib {341 pub fn openW(path_w: [*:0]const u16) !WindowsDynLib {
lib/std/fs.zig+11-11
...@@ -199,7 +199,7 @@ pub const AtomicFile = struct {...@@ -199,7 +199,7 @@ pub const AtomicFile = struct {
199 if (std.Target.current.os.tag == .windows) {199 if (std.Target.current.os.tag == .windows) {
200 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_basename);200 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_basename);
201 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);201 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);
203 self.file_exists = false;203 self.file_exists = false;
204 } else {204 } else {
205 const dest_path_c = try os.toPosixPath(self.dest_basename);205 const dest_path_c = try os.toPosixPath(self.dest_basename);
...@@ -582,7 +582,7 @@ pub const Dir = struct {...@@ -582,7 +582,7 @@ pub const Dir = struct {
582 pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {582 pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
583 if (builtin.os.tag == .windows) {583 if (builtin.os.tag == .windows) {
584 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);584 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
585 return self.openFileW(&path_w, flags);585 return self.openFileW(path_w.span(), flags);
586 }586 }
587 const path_c = try os.toPosixPath(sub_path);587 const path_c = try os.toPosixPath(sub_path);
588 return self.openFileZ(&path_c, flags);588 return self.openFileZ(&path_c, flags);
...@@ -594,7 +594,7 @@ pub const Dir = struct {...@@ -594,7 +594,7 @@ pub const Dir = struct {
594 pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {594 pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
595 if (builtin.os.tag == .windows) {595 if (builtin.os.tag == .windows) {
596 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);596 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
597 return self.openFileW(&path_w, flags);597 return self.openFileW(path_w.span(), flags);
598 }598 }
599599
600 // Use the O_ locking flags if the os supports them600 // Use the O_ locking flags if the os supports them
...@@ -669,7 +669,7 @@ pub const Dir = struct {...@@ -669,7 +669,7 @@ pub const Dir = struct {
669 pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {669 pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
670 if (builtin.os.tag == .windows) {670 if (builtin.os.tag == .windows) {
671 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);671 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
672 return self.createFileW(&path_w, flags);672 return self.createFileW(path_w.span(), flags);
673 }673 }
674 const path_c = try os.toPosixPath(sub_path);674 const path_c = try os.toPosixPath(sub_path);
675 return self.createFileZ(&path_c, flags);675 return self.createFileZ(&path_c, flags);
...@@ -681,7 +681,7 @@ pub const Dir = struct {...@@ -681,7 +681,7 @@ pub const Dir = struct {
681 pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {681 pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
682 if (builtin.os.tag == .windows) {682 if (builtin.os.tag == .windows) {
683 const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);683 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);
685 }685 }
686686
687 // Use the O_ locking flags if the os supports them687 // Use the O_ locking flags if the os supports them
...@@ -832,7 +832,7 @@ pub const Dir = struct {...@@ -832,7 +832,7 @@ pub const Dir = struct {
832 pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {832 pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {
833 if (builtin.os.tag == .windows) {833 if (builtin.os.tag == .windows) {
834 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);834 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);
836 } else {836 } else {
837 const sub_path_c = try os.toPosixPath(sub_path);837 const sub_path_c = try os.toPosixPath(sub_path);
838 return self.openDirZ(&sub_path_c, args);838 return self.openDirZ(&sub_path_c, args);
...@@ -845,7 +845,7 @@ pub const Dir = struct {...@@ -845,7 +845,7 @@ pub const Dir = struct {
845 pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) OpenError!Dir {845 pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) OpenError!Dir {
846 if (builtin.os.tag == .windows) {846 if (builtin.os.tag == .windows) {
847 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);847 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);
849 } else if (!args.iterate) {849 } else if (!args.iterate) {
850 const O_PATH = if (@hasDecl(os, "O_PATH")) os.O_PATH else 0;850 const O_PATH = if (@hasDecl(os, "O_PATH")) os.O_PATH else 0;
851 return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | O_PATH);851 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 {...@@ -987,7 +987,7 @@ pub const Dir = struct {
987 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {987 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {
988 if (builtin.os.tag == .windows) {988 if (builtin.os.tag == .windows) {
989 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);989 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);
991 }991 }
992 const sub_path_c = try os.toPosixPath(sub_path);992 const sub_path_c = try os.toPosixPath(sub_path);
993 return self.deleteDirZ(&sub_path_c);993 return self.deleteDirZ(&sub_path_c);
...@@ -1246,7 +1246,7 @@ pub const Dir = struct {...@@ -1246,7 +1246,7 @@ pub const Dir = struct {
1246 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {1246 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {
1247 if (builtin.os.tag == .windows) {1247 if (builtin.os.tag == .windows) {
1248 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);1248 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);
1250 }1250 }
1251 const path_c = try os.toPosixPath(sub_path);1251 const path_c = try os.toPosixPath(sub_path);
1252 return self.accessZ(&path_c, flags);1252 return self.accessZ(&path_c, flags);
...@@ -1256,7 +1256,7 @@ pub const Dir = struct {...@@ -1256,7 +1256,7 @@ pub const Dir = struct {
1256 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {1256 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {
1257 if (builtin.os.tag == .windows) {1257 if (builtin.os.tag == .windows) {
1258 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path);1258 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);
1260 }1260 }
1261 const os_mode = if (flags.write and flags.read)1261 const os_mode = if (flags.write and flags.read)
1262 @as(u32, os.R_OK | os.W_OK)1262 @as(u32, os.R_OK | os.W_OK)
...@@ -1596,7 +1596,7 @@ pub fn openSelfExe() OpenSelfExeError!File {...@@ -1596,7 +1596,7 @@ pub fn openSelfExe() OpenSelfExeError!File {
1596 if (builtin.os.tag == .windows) {1596 if (builtin.os.tag == .windows) {
1597 const wide_slice = selfExePathW();1597 const wide_slice = selfExePathW();
1598 const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);1598 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(), .{});
1600 }1600 }
1601 var buf: [MAX_PATH_BYTES]u8 = undefined;1601 var buf: [MAX_PATH_BYTES]u8 = undefined;
1602 const self_exe_path = try selfExePath(&buf);1602 const self_exe_path = try selfExePath(&buf);
lib/std/os.zig+23-23
...@@ -857,7 +857,7 @@ pub const OpenError = error{...@@ -857,7 +857,7 @@ pub const OpenError = error{
857pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t {857pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t {
858 if (std.Target.current.os.tag == .windows) {858 if (std.Target.current.os.tag == .windows) {
859 const file_path_w = try windows.sliceToPrefixedFileW(file_path);859 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);
861 }861 }
862 const file_path_c = try toPosixPath(file_path);862 const file_path_c = try toPosixPath(file_path);
863 return openZ(&file_path_c, flags, perm);863 return openZ(&file_path_c, flags, perm);
...@@ -870,7 +870,7 @@ pub const openC = @compileError("deprecated: renamed to openZ");...@@ -870,7 +870,7 @@ pub const openC = @compileError("deprecated: renamed to openZ");
870pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t {870pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t {
871 if (std.Target.current.os.tag == .windows) {871 if (std.Target.current.os.tag == .windows) {
872 const file_path_w = try windows.cStrToPrefixedFileW(file_path);872 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);
874 }874 }
875 while (true) {875 while (true) {
876 const rc = system.open(file_path, flags, perm);876 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!...@@ -1317,7 +1317,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
1317 if (builtin.os.tag == .windows) {1317 if (builtin.os.tag == .windows) {
1318 const target_path_w = try windows.sliceToPrefixedFileW(target_path);1318 const target_path_w = try windows.sliceToPrefixedFileW(target_path);
1319 const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);1319 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);
1321 } else {1321 } else {
1322 const target_path_c = try toPosixPath(target_path);1322 const target_path_c = try toPosixPath(target_path);
1323 const sym_link_path_c = try toPosixPath(sym_link_path);1323 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...@@ -1333,7 +1333,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
1333 if (builtin.os.tag == .windows) {1333 if (builtin.os.tag == .windows) {
1334 const target_path_w = try windows.cStrToPrefixedFileW(target_path);1334 const target_path_w = try windows.cStrToPrefixedFileW(target_path);
1335 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);1335 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);
1337 }1337 }
1338 switch (errno(system.symlink(target_path, sym_link_path))) {1338 switch (errno(system.symlink(target_path, sym_link_path))) {
1339 0 => return,1339 0 => return,
...@@ -1409,7 +1409,7 @@ pub const UnlinkError = error{...@@ -1409,7 +1409,7 @@ pub const UnlinkError = error{
1409pub fn unlink(file_path: []const u8) UnlinkError!void {1409pub fn unlink(file_path: []const u8) UnlinkError!void {
1410 if (builtin.os.tag == .windows) {1410 if (builtin.os.tag == .windows) {
1411 const file_path_w = try windows.sliceToPrefixedFileW(file_path);1411 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);
1413 } else {1413 } else {
1414 const file_path_c = try toPosixPath(file_path);1414 const file_path_c = try toPosixPath(file_path);
1415 return unlinkZ(&file_path_c);1415 return unlinkZ(&file_path_c);
...@@ -1422,7 +1422,7 @@ pub const unlinkC = @compileError("deprecated: renamed to unlinkZ");...@@ -1422,7 +1422,7 @@ pub const unlinkC = @compileError("deprecated: renamed to unlinkZ");
1422pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {1422pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
1423 if (builtin.os.tag == .windows) {1423 if (builtin.os.tag == .windows) {
1424 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1424 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);
1426 }1426 }
1427 switch (errno(system.unlink(file_path))) {1427 switch (errno(system.unlink(file_path))) {
1428 0 => return,1428 0 => return,
...@@ -1453,7 +1453,7 @@ pub const UnlinkatError = UnlinkError || error{...@@ -1453,7 +1453,7 @@ pub const UnlinkatError = UnlinkError || error{
1453pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {1453pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
1454 if (builtin.os.tag == .windows) {1454 if (builtin.os.tag == .windows) {
1455 const file_path_w = try windows.sliceToPrefixedFileW(file_path);1455 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);
1457 }1457 }
1458 const file_path_c = try toPosixPath(file_path);1458 const file_path_c = try toPosixPath(file_path);
1459 return unlinkatZ(dirfd, &file_path_c, flags);1459 return unlinkatZ(dirfd, &file_path_c, flags);
...@@ -1465,7 +1465,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");...@@ -1465,7 +1465,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");
1465pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {1465pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {
1466 if (builtin.os.tag == .windows) {1466 if (builtin.os.tag == .windows) {
1467 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);1467 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);
1469 }1469 }
1470 switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {1470 switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {
1471 0 => return,1471 0 => return,
...@@ -1580,7 +1580,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {...@@ -1580,7 +1580,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
1580 if (builtin.os.tag == .windows) {1580 if (builtin.os.tag == .windows) {
1581 const old_path_w = try windows.sliceToPrefixedFileW(old_path);1581 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
1582 const new_path_w = try windows.sliceToPrefixedFileW(new_path);1582 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);
1584 } else {1584 } else {
1585 const old_path_c = try toPosixPath(old_path);1585 const old_path_c = try toPosixPath(old_path);
1586 const new_path_c = try toPosixPath(new_path);1586 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...@@ -1595,7 +1595,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi
1595 if (builtin.os.tag == .windows) {1595 if (builtin.os.tag == .windows) {
1596 const old_path_w = try windows.cStrToPrefixedFileW(old_path);1596 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
1597 const new_path_w = try windows.cStrToPrefixedFileW(new_path);1597 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);
1599 }1599 }
1600 switch (errno(system.rename(old_path, new_path))) {1600 switch (errno(system.rename(old_path, new_path))) {
1601 0 => return,1601 0 => return,
...@@ -1638,7 +1638,7 @@ pub fn renameat(...@@ -1638,7 +1638,7 @@ pub fn renameat(
1638 if (builtin.os.tag == .windows) {1638 if (builtin.os.tag == .windows) {
1639 const old_path_w = try windows.sliceToPrefixedFileW(old_path);1639 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
1640 const new_path_w = try windows.sliceToPrefixedFileW(new_path);1640 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);
1642 } else {1642 } else {
1643 const old_path_c = try toPosixPath(old_path);1643 const old_path_c = try toPosixPath(old_path);
1644 const new_path_c = try toPosixPath(new_path);1644 const new_path_c = try toPosixPath(new_path);
...@@ -1656,7 +1656,7 @@ pub fn renameatZ(...@@ -1656,7 +1656,7 @@ pub fn renameatZ(
1656 if (builtin.os.tag == .windows) {1656 if (builtin.os.tag == .windows) {
1657 const old_path_w = try windows.cStrToPrefixedFileW(old_path);1657 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
1658 const new_path_w = try windows.cStrToPrefixedFileW(new_path);1658 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);
1660 }1660 }
16611661
1662 switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {1662 switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {
...@@ -1760,7 +1760,7 @@ pub const MakeDirError = error{...@@ -1760,7 +1760,7 @@ pub const MakeDirError = error{
1760pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {1760pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
1761 if (builtin.os.tag == .windows) {1761 if (builtin.os.tag == .windows) {
1762 const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path);1762 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);
1764 } else {1764 } else {
1765 const sub_dir_path_c = try toPosixPath(sub_dir_path);1765 const sub_dir_path_c = try toPosixPath(sub_dir_path);
1766 return mkdiratZ(dir_fd, &sub_dir_path_c, mode);1766 return mkdiratZ(dir_fd, &sub_dir_path_c, mode);
...@@ -1772,7 +1772,7 @@ pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ");...@@ -1772,7 +1772,7 @@ pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ");
1772pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void {1772pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
1773 if (builtin.os.tag == .windows) {1773 if (builtin.os.tag == .windows) {
1774 const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path);1774 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);
1776 }1776 }
1777 switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {1777 switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {
1778 0 => return,1778 0 => return,
...@@ -1816,7 +1816,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {...@@ -1816,7 +1816,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
1816pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {1816pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
1817 if (builtin.os.tag == .windows) {1817 if (builtin.os.tag == .windows) {
1818 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1818 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);
1820 windows.CloseHandle(sub_dir_handle);1820 windows.CloseHandle(sub_dir_handle);
1821 return;1821 return;
1822 }1822 }
...@@ -1857,7 +1857,7 @@ pub const DeleteDirError = error{...@@ -1857,7 +1857,7 @@ pub const DeleteDirError = error{
1857pub fn rmdir(dir_path: []const u8) DeleteDirError!void {1857pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
1858 if (builtin.os.tag == .windows) {1858 if (builtin.os.tag == .windows) {
1859 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);1859 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);
1861 } else {1861 } else {
1862 const dir_path_c = try toPosixPath(dir_path);1862 const dir_path_c = try toPosixPath(dir_path);
1863 return rmdirZ(&dir_path_c);1863 return rmdirZ(&dir_path_c);
...@@ -1870,7 +1870,7 @@ pub const rmdirC = @compileError("deprecated: renamed to rmdirZ");...@@ -1870,7 +1870,7 @@ pub const rmdirC = @compileError("deprecated: renamed to rmdirZ");
1870pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {1870pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
1871 if (builtin.os.tag == .windows) {1871 if (builtin.os.tag == .windows) {
1872 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1872 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);
1874 }1874 }
1875 switch (errno(system.rmdir(dir_path))) {1875 switch (errno(system.rmdir(dir_path))) {
1876 0 => return,1876 0 => return,
...@@ -2880,7 +2880,7 @@ pub const AccessError = error{...@@ -2880,7 +2880,7 @@ pub const AccessError = error{
2880pub fn access(path: []const u8, mode: u32) AccessError!void {2880pub fn access(path: []const u8, mode: u32) AccessError!void {
2881 if (builtin.os.tag == .windows) {2881 if (builtin.os.tag == .windows) {
2882 const path_w = try windows.sliceToPrefixedFileW(path);2882 const path_w = try windows.sliceToPrefixedFileW(path);
2883 _ = try windows.GetFileAttributesW(&path_w);2883 _ = try windows.GetFileAttributesW(path_w.span().ptr);
2884 return;2884 return;
2885 }2885 }
2886 const path_c = try toPosixPath(path);2886 const path_c = try toPosixPath(path);
...@@ -2893,7 +2893,7 @@ pub const accessC = @compileError("Deprecated in favor of `accessZ`");...@@ -2893,7 +2893,7 @@ pub const accessC = @compileError("Deprecated in favor of `accessZ`");
2893pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {2893pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
2894 if (builtin.os.tag == .windows) {2894 if (builtin.os.tag == .windows) {
2895 const path_w = try windows.cStrToPrefixedFileW(path);2895 const path_w = try windows.cStrToPrefixedFileW(path);
2896 _ = try windows.GetFileAttributesW(&path_w);2896 _ = try windows.GetFileAttributesW(path_w.span().ptr);
2897 return;2897 return;
2898 }2898 }
2899 switch (errno(system.access(path, mode))) {2899 switch (errno(system.access(path, mode))) {
...@@ -2934,7 +2934,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v...@@ -2934,7 +2934,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v
2934pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {2934pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
2935 if (builtin.os.tag == .windows) {2935 if (builtin.os.tag == .windows) {
2936 const path_w = try windows.sliceToPrefixedFileW(path);2936 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);
2938 }2938 }
2939 const path_c = try toPosixPath(path);2939 const path_c = try toPosixPath(path);
2940 return faccessatZ(dirfd, &path_c, mode, flags);2940 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...@@ -2944,7 +2944,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr
2944pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {2944pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
2945 if (builtin.os.tag == .windows) {2945 if (builtin.os.tag == .windows) {
2946 const path_w = try windows.cStrToPrefixedFileW(path);2946 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);
2948 }2948 }
2949 switch (errno(system.faccessat(dirfd, path, mode, flags))) {2949 switch (errno(system.faccessat(dirfd, path, mode, flags))) {
2950 0 => return,2950 0 => return,
...@@ -3299,7 +3299,7 @@ pub const RealPathError = error{...@@ -3299,7 +3299,7 @@ pub const RealPathError = error{
3299pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {3299pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
3300 if (builtin.os.tag == .windows) {3300 if (builtin.os.tag == .windows) {
3301 const pathname_w = try windows.sliceToPrefixedFileW(pathname);3301 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
3302 return realpathW(&pathname_w, out_buffer);3302 return realpathW(pathname_w.span().ptr, out_buffer);
3303 }3303 }
3304 const pathname_c = try toPosixPath(pathname);3304 const pathname_c = try toPosixPath(pathname);
3305 return realpathZ(&pathname_c, out_buffer);3305 return realpathZ(&pathname_c, out_buffer);
...@@ -3311,7 +3311,7 @@ pub const realpathC = @compileError("deprecated: renamed realpathZ");...@@ -3311,7 +3311,7 @@ pub const realpathC = @compileError("deprecated: renamed realpathZ");
3311pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {3311pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
3312 if (builtin.os.tag == .windows) {3312 if (builtin.os.tag == .windows) {
3313 const pathname_w = try windows.cStrToPrefixedFileW(pathname);3313 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
3314 return realpathW(&pathname_w, out_buffer);3314 return realpathW(pathname_w.span().ptr, out_buffer);
3315 }3315 }
3316 if (builtin.os.tag == .linux and !builtin.link_libc) {3316 if (builtin.os.tag == .linux and !builtin.link_libc) {
3317 const fd = openZ(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0) catch |err| switch (err) {3317 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(...@@ -59,7 +59,7 @@ pub fn CreateFile(
59 hTemplateFile: ?HANDLE,59 hTemplateFile: ?HANDLE,
60) CreateFileError!HANDLE {60) CreateFileError!HANDLE {
61 const file_path_w = try sliceToPrefixedFileW(file_path);61 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);
63}63}
6464
65pub fn CreateFileW(65pub fn CreateFileW(
...@@ -116,10 +116,10 @@ pub const OpenFileOptions = struct {...@@ -116,10 +116,10 @@ pub const OpenFileOptions = struct {
116/// TODO when share_access_nonblocking is false, this implementation uses116/// TODO when share_access_nonblocking is false, this implementation uses
117/// untinterruptible sleep() to block. This is not the final iteration of the API.117/// untinterruptible sleep() to block. This is not the final iteration of the API.
118pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HANDLE {118pub 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{'.'})) {
120 return error.IsDir;120 return error.IsDir;
121 }121 }
122 if (mem.eql(u16, sub_path_w, "..")) {122 if (mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' })) {
123 return error.IsDir;123 return error.IsDir;
124 }124 }
125125
...@@ -199,7 +199,7 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -199,7 +199,7 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
199199
200pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE {200pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE {
201 const nameW = try sliceToPrefixedFileW(name);201 const nameW = try sliceToPrefixedFileW(name);
202 return CreateEventExW(attributes, &nameW, flags, desired_access);202 return CreateEventExW(attributes, nameW.span().ptr, flags, desired_access);
203}203}
204204
205pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE {205pub 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...@@ -332,42 +332,6 @@ pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, millisec
332 }332 }
333}333}
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
371pub const CreateIoCompletionPortError = error{Unexpected};335pub const CreateIoCompletionPortError = error{Unexpected};
372336
373pub fn CreateIoCompletionPort(337pub fn CreateIoCompletionPort(
...@@ -644,7 +608,7 @@ pub fn CreateSymbolicLink(...@@ -644,7 +608,7 @@ pub fn CreateSymbolicLink(
644) CreateSymbolicLinkError!void {608) CreateSymbolicLinkError!void {
645 const sym_link_path_w = try sliceToPrefixedFileW(sym_link_path);609 const sym_link_path_w = try sliceToPrefixedFileW(sym_link_path);
646 const target_path_w = try sliceToPrefixedFileW(target_path);610 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);
648}612}
649613
650pub fn CreateSymbolicLinkW(614pub fn CreateSymbolicLinkW(
...@@ -669,7 +633,7 @@ pub const DeleteFileError = error{...@@ -669,7 +633,7 @@ pub const DeleteFileError = error{
669633
670pub fn DeleteFile(filename: []const u8) DeleteFileError!void {634pub fn DeleteFile(filename: []const u8) DeleteFileError!void {
671 const filename_w = try sliceToPrefixedFileW(filename);635 const filename_w = try sliceToPrefixedFileW(filename);
672 return DeleteFileW(&filename_w);636 return DeleteFileW(filename_w.span().ptr);
673}637}
674638
675pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void {639pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void {
...@@ -691,7 +655,7 @@ pub const MoveFileError = error{Unexpected};...@@ -691,7 +655,7 @@ pub const MoveFileError = error{Unexpected};
691pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) MoveFileError!void {655pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) MoveFileError!void {
692 const old_path_w = try sliceToPrefixedFileW(old_path);656 const old_path_w = try sliceToPrefixedFileW(old_path);
693 const new_path_w = try sliceToPrefixedFileW(new_path);657 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);
695}659}
696660
697pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void {661pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void {
...@@ -716,7 +680,7 @@ pub const CreateDirectoryError = error{...@@ -716,7 +680,7 @@ pub const CreateDirectoryError = error{
716/// Returns an open directory handle which the caller is responsible for closing with `CloseHandle`.680/// Returns an open directory handle which the caller is responsible for closing with `CloseHandle`.
717pub fn CreateDirectory(dir: ?HANDLE, pathname: []const u8, sa: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!HANDLE {681pub fn CreateDirectory(dir: ?HANDLE, pathname: []const u8, sa: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!HANDLE {
718 const pathname_w = try sliceToPrefixedFileW(pathname);682 const pathname_w = try sliceToPrefixedFileW(pathname);
719 return CreateDirectoryW(dir, &pathname_w, sa);683 return CreateDirectoryW(dir, pathname_w.span().ptr, sa);
720}684}
721685
722/// Same as `CreateDirectory` except takes a WTF-16 encoded path.686/// Same as `CreateDirectory` except takes a WTF-16 encoded path.
...@@ -784,7 +748,7 @@ pub const RemoveDirectoryError = error{...@@ -784,7 +748,7 @@ pub const RemoveDirectoryError = error{
784748
785pub fn RemoveDirectory(dir_path: []const u8) RemoveDirectoryError!void {749pub fn RemoveDirectory(dir_path: []const u8) RemoveDirectoryError!void {
786 const dir_path_w = try sliceToPrefixedFileW(dir_path);750 const dir_path_w = try sliceToPrefixedFileW(dir_path);
787 return RemoveDirectoryW(&dir_path_w);751 return RemoveDirectoryW(dir_path_w.span().ptr);
788}752}
789753
790pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void {754pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void {
...@@ -913,7 +877,7 @@ pub const GetFileAttributesError = error{...@@ -913,7 +877,7 @@ pub const GetFileAttributesError = error{
913877
914pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {878pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {
915 const filename_w = try sliceToPrefixedFileW(filename);879 const filename_w = try sliceToPrefixedFileW(filename);
916 return GetFileAttributesW(&filename_w);880 return GetFileAttributesW(filename_w.span().ptr);
917}881}
918882
919pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD {883pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD {
...@@ -1253,34 +1217,22 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME {...@@ -1253,34 +1217,22 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME {
1253 };1217 };
1254}1218}
12551219
1256pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 {1220pub const PathSpace = struct {
1257 return sliceToPrefixedFileW(mem.spanZ(s));1221 data: [PATH_MAX_WIDE:0]u16,
1258}1222 len: usize,
1259
1260pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE:0]u16 {
1261 return sliceToPrefixedSuffixedFileW(s, &[_]u16{});
1262}
12631223
1264/// Assumes an absolute path.1224 pub fn span(self: PathSpace) [:0]const u16 {
1265pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 {1225 return self.data[0..self.len :0];
1266 // TODO https://github.com/ziglang/zig/issues/27651226 }
1267 var result: [PATH_MAX_WIDE:0]u16 = undefined;1227};
12681228
1269 const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: {1229pub fn cStrToPrefixedFileW(s: [*:0]const u8) !PathSpace {
1270 const prefix = [_]u16{ '\\', '?', '?', '\\' };1230 return sliceToPrefixedFileW(mem.spanZ(s));
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;
1279}1231}
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 {
1282 // TODO https://github.com/ziglang/zig/issues/27651234 // 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;
1284 for (s) |byte| {1236 for (s) |byte| {
1285 switch (byte) {1237 switch (byte) {
1286 '*', '?', '"', '<', '>', '|' => return error.BadPathName,1238 '*', '?', '"', '<', '>', '|' => return error.BadPathName,
...@@ -1289,25 +1241,46 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)...@@ -1289,25 +1241,46 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
1289 }1241 }
1290 const start_index = if (mem.startsWith(u8, s, "\\?") or !std.fs.path.isAbsolute(s)) 0 else blk: {1242 const start_index = if (mem.startsWith(u8, s, "\\?") or !std.fs.path.isAbsolute(s)) 0 else blk: {
1291 const prefix = [_]u16{ '\\', '?', '?', '\\' };1243 const prefix = [_]u16{ '\\', '?', '?', '\\' };
1292 mem.copy(u16, result[0..], &prefix);1244 mem.copy(u16, path_space.data[0..], &prefix);
1293 break :blk prefix.len;1245 break :blk prefix.len;
1294 };1246 };
1295 const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);1247 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
1296 if (end_index + suffix.len > result.len) return error.NameTooLong;1248 if (path_space.len > path_space.data.len) return error.NameTooLong;
1297 // > File I/O functions in the Windows API convert "/" to "\" as part of1249 // > File I/O functions in the Windows API convert "/" to "\" as part of
1298 // > converting the name to an NT-style name, except when using the "\\?\"1250 // > converting the name to an NT-style name, except when using the "\\?\"
1299 // > prefix as detailed in the following sections.1251 // > prefix as detailed in the following sections.
1300 // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation1252 // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
1301 // Because we want the larger maximum path length for absolute paths, we1253 // Because we want the larger maximum path length for absolute paths, we
1302 // convert forward slashes to backward slashes here.1254 // convert forward slashes to backward slashes here.
1303 for (result[0..end_index]) |*elem| {1255 for (path_space.data[0..path_space.len]) |*elem| {
1304 if (elem.* == '/') {1256 if (elem.* == '/') {
1305 elem.* = '\\';1257 elem.* = '\\';
1306 }1258 }
1307 }1259 }
1308 mem.copy(u16, result[end_index..], suffix);1260 path_space.data[path_space.len] = 0;
1309 result[end_index + suffix.len] = 0;1261 return path_space;
1310 return result;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;
1311}1284}
13121285
1313inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {1286inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {