blob: 3b507cb5b92888ef86d1931e85112aefb2bbc869 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// +build !build_with_native_toolchain
package pkgfs
import (
"strings"
"sync"
"time"
"go.fuchsia.dev/fuchsia/src/lib/thinfs/fs"
)
type rootDirectory struct {
unsupportedDirectory
fs *Filesystem
mu sync.RWMutex
dirs map[string]fs.Directory
}
func (d *rootDirectory) Lock() {
d.mu.Lock()
}
func (d *rootDirectory) Unlock() {
d.mu.Unlock()
}
func (d *rootDirectory) Dup() (fs.Directory, error) {
return d, nil
}
func (d *rootDirectory) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
name = clean(name)
if name == "" {
return nil, d, nil, nil
}
parts := strings.SplitN(name, "/", 2)
d.mu.RLock()
subdir, ok := d.dirs[parts[0]]
d.mu.RUnlock()
if !ok {
return nil, nil, nil, fs.ErrNotFound
}
if len(parts) == 1 {
return nil, subdir, nil, nil
}
return subdir.Open(parts[1], flags)
}
func (d *rootDirectory) Read() ([]fs.Dirent, error) {
d.mu.RLock()
dirs := make([]fs.Dirent, 0, len(d.dirs))
for n := range d.dirs {
dirs = append(dirs, dirDirEnt(n))
}
d.mu.RUnlock()
return dirs, nil
}
func (d *rootDirectory) Close() error {
return nil
}
func (d *rootDirectory) Stat() (int64, time.Time, time.Time, error) {
return 0, d.fs.mountTime, d.fs.mountTime, nil
}
// setDir sets the given path within the root directory to be served by the given fs.Directory
func (d *rootDirectory) setDir(path string, newDir fs.Directory) {
d.mu.Lock()
defer d.mu.Unlock()
d.dirs[path] = newDir
}
func (d *rootDirectory) dir(path string) fs.Directory {
d.mu.RLock()
defer d.mu.RUnlock()
return d.dirLocked(path)
}
func (d *rootDirectory) dirLocked(path string) fs.Directory {
return d.dirs[path]
}