From d20a4c2403edf07f05eb024e3af568782303ce97 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 10 Oct 2024 11:56:56 +0200 Subject: [PATCH] syscall: support more flags when opening directories on Windows syscall.Open was artificially limiting the flags that were eligible to open directories on Windows. This change extend the cases where we pass FILE_FLAG_BACKUP_SEMANTICS to all flag combinations allowed by Unix. Change-Id: Ia7c083bcba070f92ea61c6d67487bdefd0d99546 Reviewed-on: https://go-review.googlesource.com/c/go/+/619295 LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui Reviewed-by: Damien Neil --- src/syscall/syscall_windows.go | 6 ++++-- src/syscall/syscall_windows_test.go | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index 84d6550c163..db1f4f2ba4d 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -388,8 +388,10 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) { if perm&S_IWRITE == 0 { attrs = FILE_ATTRIBUTE_READONLY } - if createmode == OPEN_EXISTING && access == GENERIC_READ { - // Necessary for opening directory handles. + if flag&O_WRONLY == 0 && flag&O_RDWR == 0 { + // We might be opening or creating a directory. + // CreateFile requires FILE_FLAG_BACKUP_SEMANTICS + // to work with directories. attrs |= FILE_FLAG_BACKUP_SEMANTICS } if flag&O_SYNC != 0 { diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go index 03821ea594d..ea1e8c9b3c2 100644 --- a/src/syscall/syscall_windows_test.go +++ b/src/syscall/syscall_windows_test.go @@ -24,8 +24,8 @@ func TestOpen_Dir(t *testing.T) { err error }{ {syscall.O_RDONLY, nil}, - {syscall.O_CREAT, syscall.ERROR_ACCESS_DENIED}, // TODO(qmuntal): should be allowed. - {syscall.O_RDONLY | syscall.O_CREAT, syscall.ERROR_ACCESS_DENIED}, // TODO(qmuntal): should be allowed. + {syscall.O_CREAT, nil}, + {syscall.O_RDONLY | syscall.O_CREAT, nil}, {syscall.O_RDONLY | syscall.O_TRUNC, syscall.ERROR_ACCESS_DENIED}, {syscall.O_WRONLY | syscall.O_RDWR, syscall.EISDIR}, {syscall.O_WRONLY, syscall.EISDIR},