mirror of
https://github.com/kemko/nomad.git
synced 2026-01-15 06:45:41 +03:00
This PR switches the Nomad repository from using govendor to Go modules for managing dependencies. Aspects of the Nomad workflow remain pretty much the same. The usual Makefile targets should continue to work as they always did. The API submodule simply defers to the parent Nomad version on the repository, keeping the semantics of API versioning that currently exists.
93 lines
2.6 KiB
Go
93 lines
2.6 KiB
Go
// +build windows
|
|
|
|
package winfile
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
// issue also described here
|
|
//https://codereview.appspot.com/8203043/
|
|
|
|
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L218
|
|
func Open(path string, mode int, perm uint32) (fd syscall.Handle, err error) {
|
|
if len(path) == 0 {
|
|
return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
|
|
}
|
|
pathp, err := syscall.UTF16PtrFromString(path)
|
|
if err != nil {
|
|
return syscall.InvalidHandle, err
|
|
}
|
|
var access uint32
|
|
switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) {
|
|
case syscall.O_RDONLY:
|
|
access = syscall.GENERIC_READ
|
|
case syscall.O_WRONLY:
|
|
access = syscall.GENERIC_WRITE
|
|
case syscall.O_RDWR:
|
|
access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
|
|
}
|
|
if mode&syscall.O_CREAT != 0 {
|
|
access |= syscall.GENERIC_WRITE
|
|
}
|
|
if mode&syscall.O_APPEND != 0 {
|
|
access &^= syscall.GENERIC_WRITE
|
|
access |= syscall.FILE_APPEND_DATA
|
|
}
|
|
sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_DELETE)
|
|
var sa *syscall.SecurityAttributes
|
|
if mode&syscall.O_CLOEXEC == 0 {
|
|
sa = makeInheritSa()
|
|
}
|
|
var createmode uint32
|
|
switch {
|
|
case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
|
|
createmode = syscall.CREATE_NEW
|
|
case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC):
|
|
createmode = syscall.CREATE_ALWAYS
|
|
case mode&syscall.O_CREAT == syscall.O_CREAT:
|
|
createmode = syscall.OPEN_ALWAYS
|
|
case mode&syscall.O_TRUNC == syscall.O_TRUNC:
|
|
createmode = syscall.TRUNCATE_EXISTING
|
|
default:
|
|
createmode = syscall.OPEN_EXISTING
|
|
}
|
|
h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, syscall.FILE_ATTRIBUTE_NORMAL, 0)
|
|
return h, e
|
|
}
|
|
|
|
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L211
|
|
func makeInheritSa() *syscall.SecurityAttributes {
|
|
var sa syscall.SecurityAttributes
|
|
sa.Length = uint32(unsafe.Sizeof(sa))
|
|
sa.InheritHandle = 1
|
|
return &sa
|
|
}
|
|
|
|
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_windows.go#L133
|
|
func OpenFile(name string, flag int, perm os.FileMode) (file *os.File, err error) {
|
|
r, e := Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
return os.NewFile(uintptr(r), name), nil
|
|
}
|
|
|
|
// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_posix.go#L61
|
|
func syscallMode(i os.FileMode) (o uint32) {
|
|
o |= uint32(i.Perm())
|
|
if i&os.ModeSetuid != 0 {
|
|
o |= syscall.S_ISUID
|
|
}
|
|
if i&os.ModeSetgid != 0 {
|
|
o |= syscall.S_ISGID
|
|
}
|
|
if i&os.ModeSticky != 0 {
|
|
o |= syscall.S_ISVTX
|
|
}
|
|
// No mapping for Go's ModeTemporary (plan9 only).
|
|
return
|
|
}
|