1
// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail
12
// issue also described here
13
//https://codereview.appspot.com/8203043/
15
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L218
16
func Open(path string, mode int, perm uint32) (fd syscall.Handle, err error) {
18
return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
20
pathp, err := syscall.UTF16PtrFromString(path)
22
return syscall.InvalidHandle, err
25
switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) {
26
case syscall.O_RDONLY:
27
access = syscall.GENERIC_READ
28
case syscall.O_WRONLY:
29
access = syscall.GENERIC_WRITE
31
access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
33
if mode&syscall.O_CREAT != 0 {
34
access |= syscall.GENERIC_WRITE
36
if mode&syscall.O_APPEND != 0 {
37
access &^= syscall.GENERIC_WRITE
38
access |= syscall.FILE_APPEND_DATA
40
sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_DELETE)
41
var sa *syscall.SecurityAttributes
42
if mode&syscall.O_CLOEXEC == 0 {
47
case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
48
createmode = syscall.CREATE_NEW
49
case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC):
50
createmode = syscall.CREATE_ALWAYS
51
case mode&syscall.O_CREAT == syscall.O_CREAT:
52
createmode = syscall.OPEN_ALWAYS
53
case mode&syscall.O_TRUNC == syscall.O_TRUNC:
54
createmode = syscall.TRUNCATE_EXISTING
56
createmode = syscall.OPEN_EXISTING
58
h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, syscall.FILE_ATTRIBUTE_NORMAL, 0)
62
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L211
63
func makeInheritSa() *syscall.SecurityAttributes {
64
var sa syscall.SecurityAttributes
65
sa.Length = uint32(unsafe.Sizeof(sa))
70
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_windows.go#L133
71
func OpenFile(name string, flag int, perm os.FileMode) (file *os.File, err error) {
72
r, e := Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
76
return os.NewFile(uintptr(r), name), nil
79
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_posix.go#L61
80
func syscallMode(i os.FileMode) (o uint32) {
82
if i&os.ModeSetuid != 0 {
85
if i&os.ModeSetgid != 0 {
88
if i&os.ModeSticky != 0 {
91
// No mapping for Go's ModeTemporary (plan9 only).