aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorConstantin Konstantinidis <constantinkonstantinidis@gmail.com>2020-08-16 13:48:09 +0200
committerAlex Brainman <alex.brainman@gmail.com>2020-09-11 22:10:02 +0000
commitd7384f36121d52191097af50d6dc12c0eb08fd75 (patch)
tree60c8e4ef9268b415d04151f460b9ece649118d8e /src/internal
parent07c1788357cfe6a4ee5f6f6a54d4fe9f579fa844 (diff)
downloadgo-d7384f36121d52191097af50d6dc12c0eb08fd75.tar.gz
go-d7384f36121d52191097af50d6dc12c0eb08fd75.zip
os: implement File.Chmod on Windows
Fixes: #39606 Change-Id: I4def67ef18bd3ff866b140f6e76cdabe5d51a1c5 Reviewed-on: https://go-review.googlesource.com/c/go/+/250077 Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/poll/fd_posix.go11
-rw-r--r--src/internal/poll/fd_unix.go11
-rw-r--r--src/internal/poll/fd_windows.go27
-rw-r--r--src/internal/syscall/windows/syscall_windows.go9
-rw-r--r--src/internal/syscall/windows/zsyscall_windows.go13
5 files changed, 60 insertions, 11 deletions
diff --git a/src/internal/poll/fd_posix.go b/src/internal/poll/fd_posix.go
index e5fb05c9c2..4edfa953a4 100644
--- a/src/internal/poll/fd_posix.go
+++ b/src/internal/poll/fd_posix.go
@@ -29,17 +29,6 @@ func (fd *FD) Shutdown(how int) error {
return syscall.Shutdown(fd.Sysfd, how)
}
-// Fchmod wraps syscall.Fchmod.
-func (fd *FD) Fchmod(mode uint32) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Fchmod(fd.Sysfd, mode)
- })
-}
-
// Fchown wraps syscall.Fchown.
func (fd *FD) Fchown(uid, gid int) error {
if err := fd.incref(); err != nil {
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go
index 1d5101eac3..f6f6c52f31 100644
--- a/src/internal/poll/fd_unix.go
+++ b/src/internal/poll/fd_unix.go
@@ -437,6 +437,17 @@ func (fd *FD) ReadDirent(buf []byte) (int, error) {
}
}
+// Fchmod wraps syscall.Fchmod.
+func (fd *FD) Fchmod(mode uint32) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Fchmod(fd.Sysfd, mode)
+ })
+}
+
// Fchdir wraps syscall.Fchdir.
func (fd *FD) Fchdir() error {
if err := fd.incref(); err != nil {
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index e1ef6199b3..d8c834f929 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -886,6 +886,33 @@ func (fd *FD) FindNextFile(data *syscall.Win32finddata) error {
return syscall.FindNextFile(fd.Sysfd, data)
}
+// Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
+func (fd *FD) Fchmod(mode uint32) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+
+ var d syscall.ByHandleFileInformation
+ if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
+ return err
+ }
+ attrs := d.FileAttributes
+ if mode&syscall.S_IWRITE != 0 {
+ attrs &^= syscall.FILE_ATTRIBUTE_READONLY
+ } else {
+ attrs |= syscall.FILE_ATTRIBUTE_READONLY
+ }
+ if attrs == d.FileAttributes {
+ return nil
+ }
+
+ var du windows.FILE_BASIC_INFO
+ du.FileAttributes = attrs
+ l := uint32(unsafe.Sizeof(d))
+ return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, uintptr(unsafe.Pointer(&du)), l)
+}
+
// Fchdir wraps syscall.Fchdir.
func (fd *FD) Fchdir() error {
if err := fd.incref(); err != nil {
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
index edf0b5a40b..1f40c11820 100644
--- a/src/internal/syscall/windows/syscall_windows.go
+++ b/src/internal/syscall/windows/syscall_windows.go
@@ -131,6 +131,14 @@ type IpAdapterAddresses struct {
/* more fields might be present here. */
}
+type FILE_BASIC_INFO struct {
+ CreationTime syscall.Filetime
+ LastAccessTime syscall.Filetime
+ LastWriteTime syscall.Filetime
+ ChangedTime syscall.Filetime
+ FileAttributes uint32
+}
+
const (
IfOperStatusUp = 1
IfOperStatusDown = 2
@@ -145,6 +153,7 @@ const (
//sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
//sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
+//sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
const (
WSA_FLAG_OVERLAPPED = 0x01
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
index ca5b4e6f16..0840dc283a 100644
--- a/src/internal/syscall/windows/zsyscall_windows.go
+++ b/src/internal/syscall/windows/zsyscall_windows.go
@@ -71,6 +71,7 @@ var (
procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups")
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
+ procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
)
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
@@ -81,6 +82,18 @@ func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapter
return
}
+func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(fileInformationClass), uintptr(buf), uintptr(bufsize), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
if r1 == 0 {