github.com/unikumab/tail@v1.0.1-0.20180514194441-a1dbeea552b7/winfile/winfile.go (about) 1 // +build windows 2 3 package winfile 4 5 import ( 6 "os" 7 "syscall" 8 "unsafe" 9 ) 10 11 // issue also described here 12 //https://codereview.appspot.com/8203043/ 13 14 // https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L218 15 func Open(path string, mode int, perm uint32) (fd syscall.Handle, err error) { 16 if len(path) == 0 { 17 return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND 18 } 19 pathp, err := syscall.UTF16PtrFromString(path) 20 if err != nil { 21 return syscall.InvalidHandle, err 22 } 23 var access uint32 24 switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) { 25 case syscall.O_RDONLY: 26 access = syscall.GENERIC_READ 27 case syscall.O_WRONLY: 28 access = syscall.GENERIC_WRITE 29 case syscall.O_RDWR: 30 access = syscall.GENERIC_READ | syscall.GENERIC_WRITE 31 } 32 if mode&syscall.O_CREAT != 0 { 33 access |= syscall.GENERIC_WRITE 34 } 35 if mode&syscall.O_APPEND != 0 { 36 access &^= syscall.GENERIC_WRITE 37 access |= syscall.FILE_APPEND_DATA 38 } 39 sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_DELETE) 40 var sa *syscall.SecurityAttributes 41 if mode&syscall.O_CLOEXEC == 0 { 42 sa = makeInheritSa() 43 } 44 var createmode uint32 45 switch { 46 case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL): 47 createmode = syscall.CREATE_NEW 48 case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC): 49 createmode = syscall.CREATE_ALWAYS 50 case mode&syscall.O_CREAT == syscall.O_CREAT: 51 createmode = syscall.OPEN_ALWAYS 52 case mode&syscall.O_TRUNC == syscall.O_TRUNC: 53 createmode = syscall.TRUNCATE_EXISTING 54 default: 55 createmode = syscall.OPEN_EXISTING 56 } 57 h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, syscall.FILE_ATTRIBUTE_NORMAL, 0) 58 return h, e 59 } 60 61 // https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L211 62 func makeInheritSa() *syscall.SecurityAttributes { 63 var sa syscall.SecurityAttributes 64 sa.Length = uint32(unsafe.Sizeof(sa)) 65 sa.InheritHandle = 1 66 return &sa 67 } 68 69 // https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_windows.go#L133 70 func OpenFile(name string, flag int, perm os.FileMode) (file *os.File, err error) { 71 r, e := Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm)) 72 if e != nil { 73 return nil, e 74 } 75 return os.NewFile(uintptr(r), name), nil 76 } 77 78 // https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_posix.go#L61 79 func syscallMode(i os.FileMode) (o uint32) { 80 o |= uint32(i.Perm()) 81 if i&os.ModeSetuid != 0 { 82 o |= syscall.S_ISUID 83 } 84 if i&os.ModeSetgid != 0 { 85 o |= syscall.S_ISGID 86 } 87 if i&os.ModeSticky != 0 { 88 o |= syscall.S_ISVTX 89 } 90 // No mapping for Go's ModeTemporary (plan9 only). 91 return 92 }