authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-15 18:55:07+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-22 08:51:22+02:00
log22362568cf309a4ad3d7e48f9e8635f7cb67fba7
tree6b4c331409595a7cf40b3cedcc582ed3fb4bc8b7
parent3ab5e6b1a97160ddadb90d627ae127a62c3cbd96

Refactor


2 files changed, 40 insertions(+), 26 deletions(-)

lib/std/os.zig+11-4
......@@ -1524,8 +1524,8 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
15241524/// or a directory. This value is ignored on all hosts except Windows where
15251525/// creating symlinks to different resource types, requires different flags.
15261526/// By default, symlink is assumed to point to a file.
1527pub const SymlinkFlags = struct{
1528 is_directory: bool = false,
1527pub const SymlinkFlags = struct {
1528 is_directory: bool = false,
15291529};
15301530
15311531pub const SymLinkError = error{
......@@ -2372,7 +2372,8 @@ pub const ReadLinkError = error{
23722372 NotDir,
23732373 InvalidUtf8,
23742374 BadPathName,
2375 /// Windows-only.
2375 /// Windows-only. This error may occur if the opened reparse point is
2376 /// of unsupported type.
23762377 UnsupportedReparsePointType,
23772378} || UnexpectedError;
23782379
......@@ -4075,7 +4076,13 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP
40754076 var procfs_buf: ["/proc/self/fd/-2147483648".len:0]u8 = undefined;
40764077 const proc_path = std.fmt.bufPrint(procfs_buf[0..], "/proc/self/fd/{}\x00", .{fd}) catch unreachable;
40774078
4078 return readlinkZ(@ptrCast([*:0]const u8, proc_path.ptr), out_buffer);
4079 const target = readlinkZ(@ptrCast([*:0]const u8, proc_path.ptr), out_buffer) catch |err| {
4080 switch (err) {
4081 error.UnsupportedReparsePointType => unreachable, // Windows only,
4082 else => |e| return e,
4083 }
4084 };
4085 return target;
40794086 }
40804087 const result_path = std.c.realpath(pathname, out_buffer) orelse switch (std.c._errno().*) {
40814088 EINVAL => unreachable,
lib/std/os/windows.zig+29-22
......@@ -1296,33 +1296,40 @@ pub fn cStrToWin32PrefixedFileW(s: [*:0]const u8) !PathSpace {
12961296/// it will get NT-style prefix `\??\` prepended automatically. For prepending
12971297/// Win32-style prefix, see `sliceToWin32PrefixedFileW` instead.
12981298pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
1299 // TODO https://github.com/ziglang/zig/issues/2765
1300 var path_space: PathSpace = undefined;
1301 const prefix_index: usize = if (mem.startsWith(u8, s, "\\??\\")) 4 else 0;
1302 for (s[prefix_index..]) |byte| {
1303 switch (byte) {
1304 '*', '?', '"', '<', '>', '|' => return error.BadPathName,
1305 else => {},
1306 }
1307 }
1308 const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {
1309 const prefix = [_]u16{ '\\', '?', '?', '\\' };
1310 mem.copy(u16, path_space.data[0..], &prefix);
1311 break :blk prefix.len;
1312 };
1313 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
1314 if (path_space.len > path_space.data.len) return error.NameTooLong;
1315 path_space.ensureNtStyle();
1316 return path_space;
1299 return sliceToPrefixedFileWInternal(s, PathPrefix.Nt);
13171300}
13181301
13191302/// Converts the path `s` to WTF16, null-terminated. If the path is absolute,
13201303/// it will get Win32-style extended prefix `\\?\` prepended automatically. For prepending
13211304/// NT-style prefix, see `sliceToPrefixedFileW` instead.
13221305pub fn sliceToWin32PrefixedFileW(s: []const u8) !PathSpace {
1306 return sliceToPrefixedFileWInternal(s, PathPrefix.Win32);
1307}
1308
1309const PathPrefix = enum {
1310 Win32,
1311 Nt,
1312
1313 fn toUtf8(self: PathPrefix) []const u8 {
1314 return switch (self) {
1315 .Win32 => "\\\\?\\",
1316 .Nt => "\\??\\",
1317 };
1318 }
1319
1320 fn toUtf16(self: PathPrefix) []const u16 {
1321 return switch (self) {
1322 .Win32 => &[_]u16{ '\\', '\\', '?', '\\' },
1323 .Nt => &[_]u16{ '\\', '?', '?', '\\' },
1324 };
1325 }
1326};
1327
1328fn sliceToPrefixedFileWInternal(s: []const u8, prefix: PathPrefix) !PathSpace {
13231329 // TODO https://github.com/ziglang/zig/issues/2765
13241330 var path_space: PathSpace = undefined;
1325 const prefix_index: usize = if (mem.startsWith(u8, s, "\\\\?\\")) 4 else 0;
1331 const prefix_utf8 = prefix.toUtf8();
1332 const prefix_index: usize = if (mem.startsWith(u8, s, prefix_utf8)) prefix_utf8.len else 0;
13261333 for (s[prefix_index..]) |byte| {
13271334 switch (byte) {
13281335 '*', '?', '"', '<', '>', '|' => return error.BadPathName,
......@@ -1330,9 +1337,9 @@ pub fn sliceToWin32PrefixedFileW(s: []const u8) !PathSpace {
13301337 }
13311338 }
13321339 const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {
1333 const prefix = [_]u16{ '\\', '\\', '?', '\\' };
1334 mem.copy(u16, path_space.data[0..], &prefix);
1335 break :blk prefix.len;
1340 const prefix_utf16 = prefix.toUtf16();
1341 mem.copy(u16, path_space.data[0..], prefix_utf16);
1342 break :blk prefix_utf16.len;
13361343 };
13371344 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
13381345 if (path_space.len > path_space.data.len) return error.NameTooLong;