Skip to content

Commit

Permalink
add os.Chown
Browse files Browse the repository at this point in the history
Signed-off-by: leongross <leon.gross@9elements.com>
  • Loading branch information
leongross committed Mar 28, 2024
1 parent a5ceb79 commit 724b52c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/os/file_anyos.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ func Chmod(name string, mode FileMode) error {
return nil
}

// Chown changes the numeric uid and gid of the named file.
// If the file is a symbolic link, it changes the uid and gid of the link's target.
// A uid or gid of -1 means to not change that value.
// If there is an error, it will be of type *PathError.
//
// On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
// EPLAN9 error, wrapped in *PathError.
func Chown(name string, uid, gid int) error {
e := ignoringEINTR(func() error {
return syscall.Chown(name, uid, gid)
})
if e != nil {
return &PathError{Op: "chown", Path: name, Err: e}
}
return nil
}

// ignoringEINTR makes a function call and repeats it if it returns an
// EINTR error. This appears to be required even though we install all
// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
Expand Down
24 changes: 24 additions & 0 deletions src/os/os_chmod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ package os_test
import (
. "os"
"runtime"
"syscall"
"testing"
)

func TestChmod(t *testing.T) {
// Chmod
f := newFile("TestChmod", t)
defer Remove(f.Name())
defer f.Close()
Expand All @@ -28,4 +30,26 @@ func TestChmod(t *testing.T) {
t.Fatalf("chmod %s %#o: %s", f.Name(), fm, err)
}
checkMode(t, f.Name(), fm)

}

func TestChown(t *testing.T) {
f := newFile("TestChown", t)
defer Remove(f.Name())
defer f.Close()

if runtime.GOOS != "windows" {
if err := Chown(f.Name(), 0, 0); err != nil {
t.Fatalf("chown %s 0 0: %s", f.Name(), err)
}

fi, err := Stat(f.Name())
if err != nil {
t.Fatalf("stat %s: %s", f.Name(), err)
}

if fi.Sys().(*syscall.Stat_t).Uid != 0 || fi.Sys().(*syscall.Stat_t).Gid != 0 {
t.Fatalf("chown %s 0 0: uid=%d gid=%d", f.Name(), fi.Sys().(*syscall.Stat_t).Uid, fi.Sys().(*syscall.Stat_t).Gid)
}
}
}
14 changes: 14 additions & 0 deletions src/syscall/syscall_libc.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,15 @@ func Unlink(path string) (err error) {
return
}

func Chown(path string, uid, gid int) (err error) {
data := cstring(path)
fail := int(libc_chown(&data[0], uid, gid))
if fail < 0 {
err = getErrno()
}
return
}

func Faccessat(dirfd int, path string, mode uint32, flags int) (err error)

func Kill(pid int, sig Signal) (err error) {
Expand Down Expand Up @@ -396,6 +405,11 @@ func libc_chdir(pathname *byte) int32
//export chmod
func libc_chmod(pathname *byte, mode uint32) int32

// int chown(const char *pathname, uid_t owner, gid_t group);
//
//export chown
func libc_chown(pathname *byte, owner, group int) int32

// int mkdir(const char *pathname, mode_t mode);
//
//export mkdir
Expand Down

0 comments on commit 724b52c

Please sign in to comment.