diff --git a/fs.go b/fs.go index b822ff3..0269156 100644 --- a/fs.go +++ b/fs.go @@ -4,7 +4,6 @@ import ( "errors" "io" "io/fs" - "time" ) var ( @@ -132,24 +131,12 @@ type Symlink interface { Readlink(link string) (string, error) } -// Change abstract the FileInfo change related operations in a storage-agnostic +// Chmod abstract the FileInfo change related operations in a storage-agnostic // interface as an extension to the Basic interface -type Change interface { +type Chmod interface { // Chmod changes the mode of the named file to mode. If the file is a // symbolic link, it changes the mode of the link's target. Chmod(name string, mode fs.FileMode) error - // Lchown 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 itself. - Lchown(name string, uid, gid int) error - // 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. - Chown(name string, uid, gid int) error - // Chtimes changes the access and modification times of the named file, - // similar to the Unix utime() or utimes() functions. - // - // The underlying filesystem may truncate or round the values to a less - // precise time unit. - Chtimes(name string, atime time.Time, mtime time.Time) error } // Chroot abstract the chroot related operations in a storage-agnostic interface diff --git a/helper/chroot/chroot.go b/helper/chroot/chroot.go index c54cd73..6a00baa 100644 --- a/helper/chroot/chroot.go +++ b/helper/chroot/chroot.go @@ -201,6 +201,15 @@ func (fs *ChrootHelper) Readlink(link string) (string, error) { return string(os.PathSeparator) + target, nil } +func (fs *ChrootHelper) Chmod(path string, mode fs.FileMode) error { + fullpath, err := fs.underlyingPath(path) + if err != nil { + return err + } + + return fs.underlying.(billy.Chmod).Chmod(fullpath, mode) +} + func (fs *ChrootHelper) Chroot(path string) (billy.Filesystem, error) { fullpath, err := fs.underlyingPath(path) if err != nil { diff --git a/memfs/memory.go b/memfs/memory.go index 6120515..d5b1b65 100644 --- a/memfs/memory.go +++ b/memfs/memory.go @@ -177,6 +177,10 @@ func (fs *Memory) Remove(filename string) error { return fs.s.Remove(filename) } +func (fs *Memory) Chmod(path string, mode gofs.FileMode) error { + return fs.s.Chmod(path, mode) +} + // Falls back to Go's filepath.Join, which works differently depending on the // OS where the code is being executed. func (fs *Memory) Join(elem ...string) string { diff --git a/memfs/storage.go b/memfs/storage.go index f7c0d1e..be0649a 100644 --- a/memfs/storage.go +++ b/memfs/storage.go @@ -222,6 +222,18 @@ func (s *storage) Remove(path string) error { return nil } +func (s *storage) Chmod(path string, mode fs.FileMode) error { + path = clean(path) + + f, has := s.Get(path) + if !has { + return os.ErrNotExist + } + + f.mode = mode + return nil +} + func clean(path string) string { return filepath.Clean(filepath.FromSlash(path)) } diff --git a/osfs/os_bound.go b/osfs/os_bound.go index 1ddf42c..41e1e42 100644 --- a/osfs/os_bound.go +++ b/osfs/os_bound.go @@ -226,6 +226,14 @@ func (fs *BoundOS) Readlink(link string) (string, error) { return os.Readlink(link) } +func (fs *BoundOS) Chmod(path string, mode fs.FileMode) error { + abspath, err := fs.abs(path) + if err != nil { + return err + } + return os.Chmod(abspath, mode) +} + // Chroot returns a new BoundOS filesystem, with the base dir set to the // result of joining the provided path with the underlying base dir. func (fs *BoundOS) Chroot(path string) (billy.Filesystem, error) { diff --git a/osfs/os_chroot.go b/osfs/os_chroot.go index c257e5e..efd28a0 100644 --- a/osfs/os_chroot.go +++ b/osfs/os_chroot.go @@ -80,6 +80,10 @@ func (fs *ChrootOS) Remove(filename string) error { return os.Remove(filename) } +func (fs *ChrootOS) Chmod(path string, mode fs.FileMode) error { + return os.Chmod(path, mode) +} + func (fs *ChrootOS) TempFile(dir, prefix string) (billy.File, error) { if err := fs.createDir(dir + string(os.PathSeparator)); err != nil { return nil, err