add chown method

This commit is contained in:
Bohdan Lisovskyi 2020-01-22 16:25:31 +02:00
parent 588a75ec4f
commit 30c3c32863
10 changed files with 92 additions and 0 deletions

View File

@ -96,6 +96,9 @@ type Fs interface {
//Chtimes changes the access and modification times of the named file //Chtimes changes the access and modification times of the named file
Chtimes(name string, atime time.Time, mtime time.Time) error Chtimes(name string, atime time.Time, mtime time.Time) error
// Chown changes uid and gid of the named file.
Chown(name string, uid, gid int) error
} }
var ( var (

View File

@ -177,4 +177,11 @@ func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
return fi, false, err return fi, false, err
} }
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)
}
// vim: ts=4 sw=4 noexpandtab nolist syn=go // vim: ts=4 sw=4 noexpandtab nolist syn=go

View File

@ -288,3 +288,24 @@ func (u *CacheOnReadFs) Create(name string) (File, error) {
} }
return &UnionFile{Base: bfh, Layer: lfh}, nil return &UnionFile{Base: bfh, Layer: lfh}, nil
} }
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)
}

View File

@ -291,3 +291,16 @@ func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error {
func (u *CopyOnWriteFs) Create(name string) (File, error) { func (u *CopyOnWriteFs) Create(name string) (File, error) {
return u.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) return u.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
} }
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)
}

View File

@ -57,6 +57,8 @@ type FileData struct {
dir bool dir bool
mode os.FileMode mode os.FileMode
modtime time.Time modtime time.Time
uid int
gid int
} }
func (d *FileData) Name() string { func (d *FileData) Name() string {
@ -95,6 +97,18 @@ func setModTime(f *FileData, mtime time.Time) {
f.modtime = mtime 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 { func GetFileInfo(f *FileData) *FileInfo {
return &FileInfo{f} return &FileInfo{f}
} }

View File

@ -358,6 +358,21 @@ func (m *MemMapFs) List() {
} }
} }
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 debugMemMapList(fs Fs) { // func debugMemMapList(fs Fs) {
// if x, ok := fs.(*MemMapFs); ok { // if x, ok := fs.(*MemMapFs); ok {
// x.List() // x.List()

4
os.go
View File

@ -99,3 +99,7 @@ func (OsFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
fi, err := os.Lstat(name) fi, err := os.Lstat(name)
return fi, true, err return fi, true, err
} }
func (OsFs) Chown(name string, uid, gid int) error {
return os.Chown(name, uid, gid)
}

View File

@ -78,3 +78,7 @@ func (r *ReadOnlyFs) MkdirAll(n string, p os.FileMode) error {
func (r *ReadOnlyFs) Create(n string) (File, error) { func (r *ReadOnlyFs) Create(n string) (File, error) {
return nil, syscall.EPERM return nil, syscall.EPERM
} }
func (r *ReadOnlyFs) Chown(n string, uid, gid int) error {
return syscall.EPERM
}

View File

@ -212,3 +212,10 @@ func (f *RegexpFile) Truncate(s int64) error {
func (f *RegexpFile) WriteString(s string) (int, error) { func (f *RegexpFile) WriteString(s string) (int, error) {
return f.f.WriteString(s) return f.f.WriteString(s)
} }
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)
}

View File

@ -127,3 +127,7 @@ func (s Fs) Chmod(name string, mode os.FileMode) error {
func (s Fs) Chtimes(name string, atime time.Time, mtime time.Time) error { func (s Fs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return s.client.Chtimes(name, atime, mtime) return s.client.Chtimes(name, atime, mtime)
} }
func (s Fs) Chown(name string, uid, gid int) error {
return s.client.Chown(name, uid, gid)
}