Skip to content

Commit

Permalink
Merge pull request #279 from mfuterko/implement-chown-functionality
Browse files Browse the repository at this point in the history
Implement chown functionality
  • Loading branch information
0xmichalis authored Dec 7, 2020
2 parents 736b98e + cdee88c commit 89dd0ad
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 10 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ arch:
go:
- "1.13"
- "1.14"
- "1.15"
- tip

os:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ AppFs.Open('/tmp/foo')
File System Methods Available:
```go
Chmod(name string, mode os.FileMode) : error
Chown(name string, uid, gid int) : error
Chtimes(name string, atime time.Time, mtime time.Time) : error
Create(name string) : File, error
Mkdir(name string, perm os.FileMode) : error
Expand Down
5 changes: 4 additions & 1 deletion afero.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,12 @@ type Fs interface {
// The name of this FileSystem
Name() string

//Chmod changes the mode of the named file to mode.
// Chmod changes the mode of the named file to mode.
Chmod(name string, mode os.FileMode) error

// Chown changes the uid and gid of the named file.
Chown(name string, uid, gid int) error

//Chtimes changes the access and modification times of the named file
Chtimes(name string, atime time.Time, mtime time.Time) error
}
Expand Down
9 changes: 7 additions & 2 deletions basepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ func (b *BasePathFs) Chmod(name string, mode os.FileMode) (err error) {
return b.source.Chmod(name, mode)
}

func (b *BasePathFs) Chown(name string, uid, gid int) (err error) {
if name, err = b.RealPath(name); err != nil {
return &os.PathError{Op: "chown", Path: name, Err: err}
}
return b.source.Chown(name, uid, gid)
}

func (b *BasePathFs) Name() string {
return "BasePathFs"
}
Expand Down Expand Up @@ -202,5 +209,3 @@ func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error) {
}
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
}

// vim: ts=4 sw=4 noexpandtab nolist syn=go
21 changes: 21 additions & 0 deletions cacheOnReadFs.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ func (u *CacheOnReadFs) Chmod(name string, mode os.FileMode) error {
return u.layer.Chmod(name, mode)
}

func (u *CacheOnReadFs) Chown(name string, uid, gid int) error {
st, _, err := u.cacheStatus(name)
if err != nil {
return err
}
switch st {
case cacheLocal:
case cacheHit:
err = u.base.Chown(name, uid, gid)
case cacheStale, cacheMiss:
if err := u.copyToLayer(name); err != nil {
return err
}
err = u.base.Chown(name, uid, gid)
}
if err != nil {
return err
}
return u.layer.Chown(name, uid, gid)
}

func (u *CacheOnReadFs) Stat(name string) (os.FileInfo, error) {
st, fi, err := u.cacheStatus(name)
if err != nil {
Expand Down
15 changes: 14 additions & 1 deletion copyOnWriteFs.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var _ Lstater = (*CopyOnWriteFs)(nil)
// a possibly writeable layer on top. Changes to the file system will only
// be made in the overlay: Changing an existing file in the base layer which
// is not present in the overlay will copy the file to the overlay ("changing"
// includes also calls to e.g. Chtimes() and Chmod()).
// includes also calls to e.g. Chtimes(), Chmod() and Chown()).
//
// Reading directories is currently only supported via Open(), not OpenFile().
type CopyOnWriteFs struct {
Expand Down Expand Up @@ -75,6 +75,19 @@ func (u *CopyOnWriteFs) Chmod(name string, mode os.FileMode) error {
return u.layer.Chmod(name, mode)
}

func (u *CopyOnWriteFs) Chown(name string, uid, gid int) error {
b, err := u.isBaseFile(name)
if err != nil {
return err
}
if b {
if err := u.copyToLayer(name); err != nil {
return err
}
}
return u.layer.Chown(name, uid, gid)
}

func (u *CopyOnWriteFs) Stat(name string) (os.FileInfo, error) {
fi, err := u.layer.Stat(name)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions httpFs.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ func (h HttpFs) Chmod(name string, mode os.FileMode) error {
return h.source.Chmod(name, mode)
}

func (h HttpFs) Chown(name string, uid, gid int) error {
return h.source.Chown(name, uid, gid)
}

func (h HttpFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return h.source.Chtimes(name, atime, mtime)
}
Expand Down
14 changes: 14 additions & 0 deletions mem/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ type FileData struct {
dir bool
mode os.FileMode
modtime time.Time
uid int
gid int
}

func (d *FileData) Name() string {
Expand Down Expand Up @@ -95,6 +97,18 @@ func setModTime(f *FileData, mtime time.Time) {
f.modtime = mtime
}

func SetUID(f *FileData, uid int) {
f.Lock()
f.uid = uid
f.Unlock()
}

func SetGID(f *FileData, gid int) {
f.Lock()
f.uid = gid
f.Unlock()
}

func GetFileInfo(f *FileData) *FileInfo {
return &FileInfo{f}
}
Expand Down
22 changes: 16 additions & 6 deletions memmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,22 @@ func (m *MemMapFs) setFileMode(name string, mode os.FileMode) error {
return nil
}

func (m *MemMapFs) Chown(name string, uid, gid int) error {
name = normalizePath(name)

m.mu.RLock()
f, ok := m.getData()[name]
m.mu.RUnlock()
if !ok {
return &os.PathError{Op: "chown", Path: name, Err: ErrFileNotFound}
}

mem.SetUID(f, uid)
mem.SetGID(f, gid)

return nil
}

func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
name = normalizePath(name)

Expand All @@ -386,9 +402,3 @@ func (m *MemMapFs) List() {
fmt.Println(x.Name(), y.Size())
}
}

// func debugMemMapList(fs Fs) {
// if x, ok := fs.(*MemMapFs); ok {
// x.List()
// }
// }
5 changes: 5 additions & 0 deletions memmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func TestPathErrors(t *testing.T) {
path2 := filepath.Join(".", "different", "path")
fs := NewMemMapFs()
perm := os.FileMode(0755)
uid := 1000
gid := 1000

// relevant functions:
// func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
Expand All @@ -54,6 +56,9 @@ func TestPathErrors(t *testing.T) {
err := fs.Chmod(path, perm)
checkPathError(t, err, "Chmod")

err = fs.Chown(path, uid, gid)
checkPathError(t, err, "Chown")

err = fs.Chtimes(path, time.Now(), time.Now())
checkPathError(t, err, "Chtimes")

Expand Down
4 changes: 4 additions & 0 deletions os.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (OsFs) Chmod(name string, mode os.FileMode) error {
return os.Chmod(name, mode)
}

func (OsFs) Chown(name string, uid, gid int) error {
return os.Chown(name, uid, gid)
}

func (OsFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return os.Chtimes(name, atime, mtime)
}
Expand Down
4 changes: 4 additions & 0 deletions readonlyfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ func (r *ReadOnlyFs) Chmod(n string, m os.FileMode) error {
return syscall.EPERM
}

func (r *ReadOnlyFs) Chown(n string, uid, gid int) error {
return syscall.EPERM
}

func (r *ReadOnlyFs) Name() string {
return "ReadOnlyFilter"
}
Expand Down
7 changes: 7 additions & 0 deletions regexpfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ func (r *RegexpFs) Chmod(name string, mode os.FileMode) error {
return r.source.Chmod(name, mode)
}

func (r *RegexpFs) Chown(name string, uid, gid int) error {
if err := r.dirOrMatches(name); err != nil {
return err
}
return r.source.Chown(name, uid, gid)
}

func (r *RegexpFs) Name() string {
return "RegexpFs"
}
Expand Down
4 changes: 4 additions & 0 deletions sftpfs/sftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ func (s Fs) Chmod(name string, mode os.FileMode) error {
return s.client.Chmod(name, mode)
}

func (s Fs) Chown(name string, uid, gid int) error {
return s.client.Chown(name, uid, gid)
}

func (s Fs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return s.client.Chtimes(name, atime, mtime)
}
2 changes: 2 additions & 0 deletions tarfs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,6 @@ func (fs *Fs) Stat(name string) (os.FileInfo, error) {

func (fs *Fs) Chmod(name string, mode os.FileMode) error { return syscall.EROFS }

func (fs *Fs) Chown(name string, uid, gid int) error { return syscall.EROFS }

func (fs *Fs) Chtimes(name string, atime time.Time, mtime time.Time) error { return syscall.EROFS }
2 changes: 2 additions & 0 deletions zipfs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,6 @@ func (fs *Fs) Name() string { return "zipfs" }

func (fs *Fs) Chmod(name string, mode os.FileMode) error { return syscall.EPERM }

func (fs *Fs) Chown(name string, uid, gid int) error { return syscall.EPERM }

func (fs *Fs) Chtimes(name string, atime time.Time, mtime time.Time) error { return syscall.EPERM }

0 comments on commit 89dd0ad

Please sign in to comment.