diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go index 0cd89d426d5..658e94c0f3c 100644 --- a/src/pkg/syscall/syscall_windows.go +++ b/src/pkg/syscall/syscall_windows.go @@ -154,6 +154,7 @@ func NewCallback(fn interface{}) uintptr //sys SetEnvironmentVariable(name *uint16, value *uint16) (errno int) = kernel32.SetEnvironmentVariableW //sys SetFileTime(handle int32, ctime *Filetime, atime *Filetime, wtime *Filetime) (errno int) //sys GetFileAttributes(name *uint16) (attrs uint32, errno int) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW +//sys SetFileAttributes(name *uint16, attrs uint32) (errno int) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.SetFileAttributesW //sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW //sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, errno int) [failretval==nil] = shell32.CommandLineToArgvW //sys LocalFree(hmem uint32) (handle uint32, errno int) [failretval!=0] @@ -718,11 +719,31 @@ func Fchdir(fd int) (errno int) { return EWINDOWS } func Link(oldpath, newpath string) (errno int) { return EWINDOWS } func Symlink(path, link string) (errno int) { return EWINDOWS } func Readlink(path string, buf []byte) (n int, errno int) { return 0, EWINDOWS } -func Chmod(path string, mode uint32) (errno int) { return EWINDOWS } -func Fchmod(fd int, mode uint32) (errno int) { return EWINDOWS } -func Chown(path string, uid int, gid int) (errno int) { return EWINDOWS } -func Lchown(path string, uid int, gid int) (errno int) { return EWINDOWS } -func Fchown(fd int, uid int, gid int) (errno int) { return EWINDOWS } + +func Chmod(path string, mode uint32) (errno int) { + attrs, errno := GetFileAttributes(StringToUTF16Ptr(path)) + if errno != 0 { + return + } + + if mode == 0 { + return EINVAL + } + + if mode&S_IWRITE != 0 { + attrs &^= FILE_ATTRIBUTE_READONLY + } else if attrs&FILE_ATTRIBUTE_READONLY == 0 { + attrs |= FILE_ATTRIBUTE_READONLY + } + + errno = SetFileAttributes(StringToUTF16Ptr(path), attrs) + return +} + +func Fchmod(fd int, mode uint32) (errno int) { return EWINDOWS } +func Chown(path string, uid int, gid int) (errno int) { return EWINDOWS } +func Lchown(path string, uid int, gid int) (errno int) { return EWINDOWS } +func Fchown(fd int, uid int, gid int) (errno int) { return EWINDOWS } func Getuid() (uid int) { return -1 } func Geteuid() (euid int) { return -1 } diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go index 46e16f43c53..7a7239b92f6 100644 --- a/src/pkg/syscall/zsyscall_windows_386.go +++ b/src/pkg/syscall/zsyscall_windows_386.go @@ -63,6 +63,7 @@ var ( procSetEnvironmentVariableW = getSysProcAddr(modkernel32, "SetEnvironmentVariableW") procSetFileTime = getSysProcAddr(modkernel32, "SetFileTime") procGetFileAttributesW = getSysProcAddr(modkernel32, "GetFileAttributesW") + procSetFileAttributesW = getSysProcAddr(modkernel32, "SetFileAttributesW") procGetCommandLineW = getSysProcAddr(modkernel32, "GetCommandLineW") procCommandLineToArgvW = getSysProcAddr(modshell32, "CommandLineToArgvW") procLocalFree = getSysProcAddr(modkernel32, "LocalFree") @@ -806,6 +807,20 @@ func GetFileAttributes(name *uint16) (attrs uint32, errno int) { return } +func SetFileAttributes(name *uint16, attrs uint32) (errno int) { + r0, _, e1 := Syscall(procSetFileAttributesW, 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + if int(r0) == 0 { + if e1 != 0 { + errno = int(e1) + } else { + errno = EINVAL + } + } else { + errno = 0 + } + return +} + func GetCommandLine() (cmd *uint16) { r0, _, _ := Syscall(procGetCommandLineW, 0, 0, 0, 0) cmd = (*uint16)(unsafe.Pointer(r0)) diff --git a/src/pkg/syscall/ztypes_windows_386.go b/src/pkg/syscall/ztypes_windows_386.go index e9ab3546193..0f5f69cfd27 100644 --- a/src/pkg/syscall/ztypes_windows_386.go +++ b/src/pkg/syscall/ztypes_windows_386.go @@ -380,6 +380,7 @@ const ( S_ISGID = 0x400 S_ISVTX = 0x200 S_IRUSR = 0x100 + S_IWRITE = 0x80 S_IWUSR = 0x80 S_IXUSR = 0x40 )