aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/fs.go3
-rw-r--r--fs/memory.go51
-rw-r--r--fs/os.go26
3 files changed, 65 insertions, 15 deletions
diff --git a/fs/fs.go b/fs/fs.go
index cbfeb44..b06ded8 100644
--- a/fs/fs.go
+++ b/fs/fs.go
@@ -29,10 +29,13 @@ type RegularFile interface {
type Dir interface {
File
Readdir() ([]File, error)
+ GetChild(name string) (File, error) // Must return os.ErrNotExist, if child doesn't exist
CreateChildFile(name string, exec bool) (RegularFile, error)
CreateChildDir(name string) (Dir, error)
CreateChildSymlink(name string, target string) (Symlink, error)
+
+ RenameChild(oldname, newname string) error
}
type Symlink interface {
diff --git a/fs/memory.go b/fs/memory.go
index 5f5d327..221ff36 100644
--- a/fs/memory.go
+++ b/fs/memory.go
@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"io"
+ "os"
"time"
)
@@ -14,7 +15,13 @@ type memfsBase struct {
mtime time.Time
}
+type memfsChild interface {
+ File
+ setName(string)
+}
+
func (b memfsBase) Name() string { return b.name }
+func (b *memfsBase) setName(n string) { b.name = n }
func (b memfsBase) Executable() bool { return b.exec }
func (b memfsBase) ModTime() time.Time { return b.mtime }
@@ -45,13 +52,13 @@ func (f memfsFile) Write(p []byte) (int, error) {
return f.content.Write(p)
}
-func (memfsBase) Close() error {
+func (memfsFile) Close() error {
return nil
}
type memfsDir struct {
memfsBase
- children map[string]File
+ children map[string]memfsChild
}
func (memfsDir) Type() FileType { return FDir }
@@ -66,6 +73,14 @@ func (d memfsDir) Readdir() ([]File, error) {
return l, nil
}
+func (d memfsDir) GetChild(name string) (File, error) {
+ c, ok := d.children[name]
+ if !ok {
+ return nil, os.ErrNotExist
+ }
+ return c, nil
+}
+
func (d memfsDir) createChildBase(name string, exec bool) memfsBase {
return memfsBase{
parent: &d,
@@ -80,17 +95,17 @@ func (d memfsDir) CreateChildFile(name string, exec bool) (RegularFile, error) {
memfsBase: d.createChildBase(name, exec),
content: new(bytes.Buffer),
}
- d.children[name] = child
- return child, nil
+ d.children[name] = &child
+ return &child, nil
}
func (d memfsDir) CreateChildDir(name string) (Dir, error) {
child := memfsDir{
memfsBase: d.createChildBase(name, true),
- children: make(map[string]File),
+ children: make(map[string]memfsChild),
}
- d.children[name] = child
- return child, nil
+ d.children[name] = &child
+ return &child, nil
}
func (d memfsDir) CreateChildSymlink(name string, target string) (Symlink, error) {
@@ -98,23 +113,37 @@ func (d memfsDir) CreateChildSymlink(name string, target string) (Symlink, error
memfsBase: d.createChildBase(name, false),
target: target,
}
- d.children[name] = child
- return child, nil
+ d.children[name] = &child
+ return &child, nil
}
func (d *memfsDir) deleteChild(name string) {
delete(d.children, name)
}
+func (d *memfsDir) RenameChild(oldname, newname string) error {
+ c, ok := d.children[oldname]
+ if !ok {
+ return os.ErrNotExist
+ }
+
+ c.setName(newname)
+
+ delete(d.children, oldname)
+ d.children[newname] = c
+
+ return nil
+}
+
func NewMemoryFSRoot(name string) Dir {
- return memfsDir{
+ return &memfsDir{
memfsBase: memfsBase{
parent: nil,
name: name,
exec: true,
mtime: time.Now(),
},
- children: make(map[string]File),
+ children: make(map[string]memfsChild),
}
}
diff --git a/fs/os.go b/fs/os.go
index f251c66..0a4f614 100644
--- a/fs/os.go
+++ b/fs/os.go
@@ -3,9 +3,14 @@ package fs
import (
"io"
"os"
+ "strings"
"time"
)
+func pathJoin(parts ...string) string {
+ return strings.Join(parts, string(os.PathSeparator))
+}
+
func openOSFile(path string) (osFile, error) {
fi, err := os.Lstat(path)
if err != nil {
@@ -79,7 +84,7 @@ func (f osFile) Readdir() (list []File, err error) {
}
list = append(list, osFile{
- fullpath: f.fullpath + string(os.PathSeparator) + fi.Name(),
+ fullpath: pathJoin(f.fullpath, fi.Name()),
fi: fi,
})
}
@@ -87,6 +92,15 @@ func (f osFile) Readdir() (list []File, err error) {
return
}
+func (f osFile) GetChild(name string) (File, error) {
+ path := pathJoin(f.fullpath, name)
+ fi, err := os.Lstat(path)
+ if err != nil {
+ return nil, err
+ }
+ return osFile{path, fi}, nil
+}
+
func perms(executable bool) os.FileMode {
if executable {
return 0755
@@ -96,7 +110,7 @@ func perms(executable bool) os.FileMode {
}
func (f osFile) CreateChildFile(name string, exec bool) (RegularFile, error) {
- p := f.fullpath + string(os.PathSeparator) + name
+ p := pathJoin(f.fullpath, name)
fh, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE, perms(exec))
if err != nil {
@@ -108,7 +122,7 @@ func (f osFile) CreateChildFile(name string, exec bool) (RegularFile, error) {
}
func (f osFile) CreateChildDir(name string) (Dir, error) {
- p := f.fullpath + string(os.PathSeparator) + name
+ p := pathJoin(f.fullpath, name)
if err := os.Mkdir(p, perms(true)); err != nil {
return nil, err
@@ -118,7 +132,7 @@ func (f osFile) CreateChildDir(name string) (Dir, error) {
}
func (f osFile) CreateChildSymlink(name string, target string) (Symlink, error) {
- p := f.fullpath + string(os.PathSeparator) + name
+ p := pathJoin(f.fullpath, name)
err := os.Symlink(target, p)
if err != nil {
@@ -128,6 +142,10 @@ func (f osFile) CreateChildSymlink(name string, target string) (Symlink, error)
return openOSFile(p)
}
+func (f osFile) RenameChild(oldname, newname string) error {
+ return os.Rename(pathJoin(f.fullpath, oldname), pathJoin(f.fullpath, newname))
+}
+
func (f osFile) Readlink() (string, error) {
return os.Readlink(f.fullpath)
}