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 {...@@ -1524,8 +1524,8 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
1524/// or a directory. This value is ignored on all hosts except Windows where1524/// or a directory. This value is ignored on all hosts except Windows where
1525/// creating symlinks to different resource types, requires different flags.1525/// creating symlinks to different resource types, requires different flags.
1526/// By default, symlink is assumed to point to a file.1526/// By default, symlink is assumed to point to a file.
1527pub const SymlinkFlags = struct{1527pub const SymlinkFlags = struct {
1528 is_directory: bool = false, 1528 is_directory: bool = false,
1529};1529};
15301530
1531pub const SymLinkError = error{1531pub const SymLinkError = error{
...@@ -2372,7 +2372,8 @@ pub const ReadLinkError = error{...@@ -2372,7 +2372,8 @@ pub const ReadLinkError = error{
2372 NotDir,2372 NotDir,
2373 InvalidUtf8,2373 InvalidUtf8,
2374 BadPathName,2374 BadPathName,
2375 /// Windows-only.2375 /// Windows-only. This error may occur if the opened reparse point is
2376 /// of unsupported type.
2376 UnsupportedReparsePointType,2377 UnsupportedReparsePointType,
2377} || UnexpectedError;2378} || UnexpectedError;
23782379
...@@ -4075,7 +4076,13 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP...@@ -4075,7 +4076,13 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP
4075 var procfs_buf: ["/proc/self/fd/-2147483648".len:0]u8 = undefined;4076 var procfs_buf: ["/proc/self/fd/-2147483648".len:0]u8 = undefined;
4076 const proc_path = std.fmt.bufPrint(procfs_buf[0..], "/proc/self/fd/{}\x00", .{fd}) catch unreachable;4077 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;
4079 }4086 }
4080 const result_path = std.c.realpath(pathname, out_buffer) orelse switch (std.c._errno().*) {4087 const result_path = std.c.realpath(pathname, out_buffer) orelse switch (std.c._errno().*) {
4081 EINVAL => unreachable,4088 EINVAL => unreachable,
lib/std/os/windows.zig+29-22
...@@ -1296,33 +1296,40 @@ pub fn cStrToWin32PrefixedFileW(s: [*:0]const u8) !PathSpace {...@@ -1296,33 +1296,40 @@ pub fn cStrToWin32PrefixedFileW(s: [*:0]const u8) !PathSpace {
1296/// it will get NT-style prefix `\??\` prepended automatically. For prepending1296/// it will get NT-style prefix `\??\` prepended automatically. For prepending
1297/// Win32-style prefix, see `sliceToWin32PrefixedFileW` instead.1297/// Win32-style prefix, see `sliceToWin32PrefixedFileW` instead.
1298pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {1298pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
1299 // TODO https://github.com/ziglang/zig/issues/27651299 return sliceToPrefixedFileWInternal(s, PathPrefix.Nt);
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;
1317}1300}
13181301
1319/// Converts the path `s` to WTF16, null-terminated. If the path is absolute,1302/// Converts the path `s` to WTF16, null-terminated. If the path is absolute,
1320/// it will get Win32-style extended prefix `\\?\` prepended automatically. For prepending1303/// it will get Win32-style extended prefix `\\?\` prepended automatically. For prepending
1321/// NT-style prefix, see `sliceToPrefixedFileW` instead.1304/// NT-style prefix, see `sliceToPrefixedFileW` instead.
1322pub fn sliceToWin32PrefixedFileW(s: []const u8) !PathSpace {1305pub 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 {
1323 // TODO https://github.com/ziglang/zig/issues/27651329 // TODO https://github.com/ziglang/zig/issues/2765
1324 var path_space: PathSpace = undefined;1330 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;
1326 for (s[prefix_index..]) |byte| {1333 for (s[prefix_index..]) |byte| {
1327 switch (byte) {1334 switch (byte) {
1328 '*', '?', '"', '<', '>', '|' => return error.BadPathName,1335 '*', '?', '"', '<', '>', '|' => return error.BadPathName,
...@@ -1330,9 +1337,9 @@ pub fn sliceToWin32PrefixedFileW(s: []const u8) !PathSpace {...@@ -1330,9 +1337,9 @@ pub fn sliceToWin32PrefixedFileW(s: []const u8) !PathSpace {
1330 }1337 }
1331 }1338 }
1332 const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {1339 const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {
1333 const prefix = [_]u16{ '\\', '\\', '?', '\\' };1340 const prefix_utf16 = prefix.toUtf16();
1334 mem.copy(u16, path_space.data[0..], &prefix);1341 mem.copy(u16, path_space.data[0..], prefix_utf16);
1335 break :blk prefix.len;1342 break :blk prefix_utf16.len;
1336 };1343 };
1337 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);1344 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
1338 if (path_space.len > path_space.data.len) return error.NameTooLong;1345 if (path_space.len > path_space.data.len) return error.NameTooLong;