return nil, &PathError{Op: "open", Path: name, Err: syscall.ENOENT}
}
path := fixLongPath(name)
- r, e := syscall.Open(path, flag|syscall.O_CLOEXEC, syscallMode(perm))
- if e != nil {
- // We should return EISDIR when we are trying to open a directory with write access.
- if e == syscall.ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
- pathp, e1 := syscall.UTF16PtrFromString(path)
- if e1 == nil {
- var fa syscall.Win32FileAttributeData
- e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
- if e1 == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- e = syscall.EISDIR
- }
- }
- }
- return nil, &PathError{Op: "open", Path: name, Err: e}
+ r, err := syscall.Open(path, flag|syscall.O_CLOEXEC, syscallMode(perm))
+ if err != nil {
+ return nil, &PathError{Op: "open", Path: name, Err: err}
}
return newFile(r, name, "file"), nil
}
}
h, err := CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
if err != nil {
+ if err == ERROR_ACCESS_DENIED && (mode&O_WRONLY != 0 || mode&O_RDWR != 0) {
+ // We should return EISDIR when we are trying to open a directory with write access.
+ fa, e1 := GetFileAttributes(pathp)
+ if e1 == nil && fa&FILE_ATTRIBUTE_DIRECTORY != 0 {
+ err = EISDIR
+ }
+ }
return InvalidHandle, err
}
if mode&O_TRUNC == O_TRUNC {
)
func TestOpen_Dir(t *testing.T) {
- dir := t.TempDir()
+ t.Parallel()
- h, err := syscall.Open(dir, syscall.O_RDONLY, 0)
- if err != nil {
- t.Fatalf("Open failed: %v", err)
- }
- syscall.CloseHandle(h)
- h, err = syscall.Open(dir, syscall.O_RDONLY|syscall.O_TRUNC, 0)
- if err == nil {
- t.Error("Open should have failed")
- } else {
- syscall.CloseHandle(h)
- }
- h, err = syscall.Open(dir, syscall.O_RDONLY|syscall.O_CREAT, 0)
- if err == nil {
- t.Error("Open should have failed")
- } else {
- syscall.CloseHandle(h)
+ dir := t.TempDir()
+ tests := []struct {
+ mode int
+ 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_RDONLY | syscall.O_TRUNC, syscall.ERROR_ACCESS_DENIED},
+ {syscall.O_WRONLY | syscall.O_RDWR, syscall.EISDIR},
+ {syscall.O_WRONLY, syscall.EISDIR},
+ {syscall.O_RDWR, syscall.EISDIR},
+ }
+ for i, tt := range tests {
+ h, err := syscall.Open(dir, tt.mode, 0)
+ if err == nil {
+ syscall.CloseHandle(h)
+ }
+ if err != tt.err {
+ t.Errorf("%d: Open got %v, want %v", i, err, tt.err)
+ }
}
}