Skip to content

Commit

Permalink
Watch.zig: remove realpath call, prefer NtCreateFile over CreateFileW
Browse files Browse the repository at this point in the history
  • Loading branch information
jayrod246 committed Jul 18, 2024
1 parent d7a632a commit faaa591
Showing 1 changed file with 45 additions and 9 deletions.
54 changes: 45 additions & 9 deletions lib/std/Build/Watch.zig
Original file line number Diff line number Diff line change
Expand Up @@ -340,19 +340,55 @@ const Os = switch (builtin.os.tag) {
const reaction_set = rs: {
const gop = try w.dir_table.getOrPut(gpa, path);
if (!gop.found_existing) {
var realpath_buf: [std.fs.max_path_bytes]u8 = undefined;
const realpath = try path.root_dir.handle.realpath(path.sub_path, &realpath_buf);
const realpath_w = try windows.sliceToPrefixedFileW(null, realpath);
const dir_handle = windows.kernel32.CreateFileW(
realpath_w.span().ptr,
windows.GENERIC_READ,
windows.FILE_SHARE_DELETE | windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE,
// The following code is a drawn out NtCreateFile call. (mostly adapted from std.fs.Dir.makeOpenDirAccessMaskW)
// It's necessary in order to get the flags are required when calling ReadDirectoryChangesW.
const root_fd = path.root_dir.handle.fd;
const sub_path = path.subPathOrDot();
const sub_path_w = try windows.sliceToPrefixedFileW(root_fd, sub_path);
const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;

var nt_name = windows.UNICODE_STRING{
.Length = @intCast(path_len_bytes),
.MaximumLength = @intCast(path_len_bytes),
.Buffer = @constCast(sub_path_w.span().ptr),
};
var attr = windows.OBJECT_ATTRIBUTES{
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
.RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else root_fd,
.Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
.ObjectName = &nt_name,
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
var io: windows.IO_STATUS_BLOCK = undefined;
var dir_handle: windows.HANDLE = undefined;
const rc = windows.ntdll.NtCreateFile(
&dir_handle,
windows.SYNCHRONIZE | windows.GENERIC_READ | windows.FILE_LIST_DIRECTORY,
&attr,
&io,
null,
windows.OPEN_EXISTING,
windows.FILE_FLAG_BACKUP_SEMANTICS | windows.FILE_FLAG_OVERLAPPED,
0,
windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,
windows.FILE_OPEN,
windows.FILE_DIRECTORY_FILE | windows.FILE_OPEN_FOR_BACKUP_INTENT,
null,
0,
);

switch (rc) {
.SUCCESS => {},
.OBJECT_NAME_INVALID => return error.BadPathName,
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
.OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
.NOT_A_DIRECTORY => return error.NotDir,
// This can happen if the directory has 'List folder contents' permission set to 'Deny'
.ACCESS_DENIED => return error.AccessDenied,
.INVALID_PARAMETER => unreachable,
else => return windows.unexpectedStatus(rc),
}

assert(dir_handle != windows.INVALID_HANDLE_VALUE);

// `dir_handle` may already be present in the table in
Expand Down

0 comments on commit faaa591

Please sign in to comment.