Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  fs.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fs

import (
 "bytes"
 "errors"
 "fmt"
 "io"
 "io/ioutil"
 "os"
 "os/user"
 "path/filepath"
 "sync"
 "time"
)

var OsFs FileSystem = osFs{}

func NewMockFs(files map[string][]byte) *MockFs {
 workDir := "/cwd"
 fs := &MockFs{
  Clock:   NewClock(time.Unix(22)),
  workDir: workDir,
 }
 fs.root = *fs.newDir()
 fs.MkDirs(workDir)

 for path, bytes := range files {
  dir := filepath.Dir(path)
  fs.MkDirs(dir)
  fs.WriteFile(path, bytes, 0777)
 }

 return fs
}

type FileSystem interface {
 // getting information about files
 Open(name string) (file io.ReadCloser, err error)
 Lstat(path string) (stats os.FileInfo, err error)
 Stat(path string) (stats os.FileInfo, err error)
 ReadDir(path string) (contents []DirEntryInfo, err error)

 InodeNumber(info os.FileInfo) (number uint64, err error)
 DeviceNumber(info os.FileInfo) (number uint64, err error)
 PermTime(info os.FileInfo) (time time.Time, err error)

 // changing contents of the filesystem
 Rename(oldPath string, newPath string) (err error)
 WriteFile(path string, data []byte, perm os.FileMode) (err error)
 Remove(path string) (err error)
 RemoveAll(path string) (err error)

 // metadata about the filesystem
 ViewId() (id string) // Some unique id of the user accessing the filesystem
}

// DentryInfo is a subset of the functionality available through os.FileInfo that might be able
// to be gleaned through only a syscall.Getdents without requiring a syscall.Lstat of every file.
type DirEntryInfo interface {
 Name() string
 Mode() os.FileMode // the file type encoded as an os.FileMode
 IsDir() bool
}

type dirEntryInfo struct {
 name       string
 mode       os.FileMode
 modeExists bool
}

var _ DirEntryInfo = os.FileInfo(nil)

func (d *dirEntryInfo) Name() string      { return d.name }
func (d *dirEntryInfo) Mode() os.FileMode { return d.mode }
func (d *dirEntryInfo) IsDir() bool       { return d.mode.IsDir() }
func (d *dirEntryInfo) String() string    { return d.name + ": " + d.mode.String() }

// osFs implements FileSystem using the local disk.
type osFs struct{}

var _ FileSystem = (*osFs)(nil)

func (osFs) Open(name string) (io.ReadCloser, error) { return os.Open(name) }

func (osFs) Lstat(path string) (stats os.FileInfo, err error) {
 return os.Lstat(path)
}

func (osFs) Stat(path string) (stats os.FileInfo, err error) {
 return os.Stat(path)
}

func (osFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
 entries, err := readdir(path)
 if err != nil {
  return nil, err
 }
 for _, entry := range entries {
  contents = append(contents, entry)
 }

 return contents, nil
}

func (osFs) Rename(oldPath string, newPath string) error {
 return os.Rename(oldPath, newPath)
}

func (osFs) WriteFile(path string, data []byte, perm os.FileMode) error {
 return ioutil.WriteFile(path, data, perm)
}

func (osFs) Remove(path string) error {
 return os.Remove(path)
}

func (osFs) RemoveAll(path string) error {
 return os.RemoveAll(path)
}

func (osFs) ViewId() (id string) {
 user, err := user.Current()
 if err != nil {
  return ""
 }
 username := user.Username

 hostname, err := os.Hostname()
 if err != nil {
  return ""
 }

 return username + "@" + hostname
}

type Clock struct {
 time time.Time
}

func NewClock(startTime time.Time) *Clock {
 return &Clock{time: startTime}

}

func (c *Clock) Tick() {
 c.time = c.time.Add(time.Microsecond)
}

func (c *Clock) Time() time.Time {
 return c.time
}

// given "/a/b/c/d", pathSplit returns ("/a/b/c", "d")
func pathSplit(path string) (dir string, leaf string) {
 dir, leaf = filepath.Split(path)
 if dir != "/" && len(dir) > 0 {
  dir = dir[:len(dir)-1]
 }
 return dir, leaf
}

// MockFs supports singlethreaded writes and multithreaded reads
type MockFs struct {
 // configuration
 viewId       string //
 deviceNumber uint64

 // implementation
 root            mockDir
 Clock           *Clock
 workDir         string
 nextInodeNumber uint64

 // history of requests, for tests to check
 StatCalls      []string
 ReadDirCalls   []string
 aggregatesLock sync.Mutex
}

var _ FileSystem = (*MockFs)(nil)

type mockInode struct {
 modTime     time.Time
 permTime    time.Time
 sys         interface{}
 inodeNumber uint64
 readErr     error
}

func (m mockInode) ModTime() time.Time {
 return m.modTime
}

func (m mockInode) Sys() interface{} {
 return m.sys
}

type mockFile struct {
 bytes []byte

 mockInode
}

type mockLink struct {
 target string

 mockInode
}

type mockDir struct {
 mockInode

 subdirs  map[string]*mockDir
 files    map[string]*mockFile
 symlinks map[string]*mockLink
}

func (m *MockFs) resolve(path string, followLastLink bool) (result string, err error) {
 if !filepath.IsAbs(path) {
  path = filepath.Join(m.workDir, path)
 }
 path = filepath.Clean(path)

 return m.followLinks(path, followLastLink, 10)
}

// note that followLinks can return a file path that doesn't exist
func (m *MockFs) followLinks(path string, followLastLink bool, count int) (canonicalPath string, err error) {
 if path == "/" {
  return path, nil
 }

 parentPath, leaf := pathSplit(path)
 if parentPath == path {
  err = fmt.Errorf("Internal error: %v yields itself as a parent", path)
  panic(err.Error())
 }

 parentPath, err = m.followLinks(parentPath, true, count)
 if err != nil {
  return "", err
 }

 parentNode, err := m.getDir(parentPath, false)
 if err != nil {
  return "", err
 }
 if parentNode.readErr != nil {
  return "", &os.PathError{
   Op:   "read",
   Path: path,
   Err:  parentNode.readErr,
  }
 }

 link, isLink := parentNode.symlinks[leaf]
 if isLink && followLastLink {
  if count <= 0 {
   // probably a loop
   return "", &os.PathError{
    Op:   "read",
    Path: path,
    Err:  fmt.Errorf("too many levels of symbolic links"),
   }
  }

  if link.readErr != nil {
   return "", &os.PathError{
    Op:   "read",
    Path: path,
    Err:  link.readErr,
   }
  }

  target := m.followLink(link, parentPath)
  return m.followLinks(target, followLastLink, count-1)
 }
 return path, nil
}

func (m *MockFs) followLink(link *mockLink, parentPath string) (result string) {
 return filepath.Clean(filepath.Join(parentPath, link.target))
}

func (m *MockFs) getFile(parentDir *mockDir, fileName string) (file *mockFile, err error) {
 file, isFile := parentDir.files[fileName]
 if !isFile {
  _, isDir := parentDir.subdirs[fileName]
  _, isLink := parentDir.symlinks[fileName]
  if isDir || isLink {
   return nil, &os.PathError{
    Op:   "open",
    Path: fileName,
    Err:  os.ErrInvalid,
   }
  }

  return nil, &os.PathError{
   Op:   "open",
   Path: fileName,
   Err:  os.ErrNotExist,
  }
 }
 if file.readErr != nil {
  return nil, &os.PathError{
   Op:   "open",
   Path: fileName,
   Err:  file.readErr,
  }
 }
 return file, nil
}

func (m *MockFs) getInode(parentDir *mockDir, name string) (inode *mockInode, err error) {
 file, isFile := parentDir.files[name]
 if isFile {
  return &file.mockInode, nil
 }
 link, isLink := parentDir.symlinks[name]
 if isLink {
  return &link.mockInode, nil
 }
 dir, isDir := parentDir.subdirs[name]
 if isDir {
  return &dir.mockInode, nil
 }
 return nil, &os.PathError{
  Op:   "stat",
  Path: name,
  Err:  os.ErrNotExist,
 }

}

func (m *MockFs) Open(path string) (io.ReadCloser, error) {
 path, err := m.resolve(path, true)
 if err != nil {
  return nil, err
 }

 if err != nil {
  return nil, err
 }

 parentPath, base := pathSplit(path)
 parentDir, err := m.getDir(parentPath, false)
 if err != nil {
  return nil, err
 }
 file, err := m.getFile(parentDir, base)
 if err != nil {
  return nil, err
 }
 return struct {
  io.Closer
  *bytes.Reader
 }{
  ioutil.NopCloser(nil),
  bytes.NewReader(file.bytes),
 }, nil

}

// a mockFileInfo is for exporting file stats in a way that satisfies the FileInfo interface
type mockFileInfo struct {
 path         string
 size         int64
 modTime      time.Time // time at which the inode's contents were modified
 permTime     time.Time // time at which the inode's permissions were modified
 mode         os.FileMode
 inodeNumber  uint64
 deviceNumber uint64
}

func (m *mockFileInfo) Name() string {
 return m.path
}

func (m *mockFileInfo) Size() int64 {
 return m.size
}

func (m *mockFileInfo) Mode() os.FileMode {
 return m.mode
}

func (m *mockFileInfo) ModTime() time.Time {
 return m.modTime
}

func (m *mockFileInfo) IsDir() bool {
 return m.mode&os.ModeDir != 0
}

func (m *mockFileInfo) Sys() interface{} {
 return nil
}

func (m *MockFs) dirToFileInfo(d *mockDir, path string) (info *mockFileInfo) {
 return &mockFileInfo{
  path:         filepath.Base(path),
  size:         1,
  modTime:      d.modTime,
  permTime:     d.permTime,
  mode:         os.ModeDir,
  inodeNumber:  d.inodeNumber,
  deviceNumber: m.deviceNumber,
 }

}

func (m *MockFs) fileToFileInfo(f *mockFile, path string) (info *mockFileInfo) {
 return &mockFileInfo{
  path:         filepath.Base(path),
  size:         1,
  modTime:      f.modTime,
  permTime:     f.permTime,
  mode:         0,
  inodeNumber:  f.inodeNumber,
  deviceNumber: m.deviceNumber,
 }
}

func (m *MockFs) linkToFileInfo(l *mockLink, path string) (info *mockFileInfo) {
 return &mockFileInfo{
  path:         filepath.Base(path),
  size:         1,
  modTime:      l.modTime,
  permTime:     l.permTime,
  mode:         os.ModeSymlink,
  inodeNumber:  l.inodeNumber,
  deviceNumber: m.deviceNumber,
 }
}

func (m *MockFs) Lstat(path string) (stats os.FileInfo, err error) {
 // update aggregates
 m.aggregatesLock.Lock()
 m.StatCalls = append(m.StatCalls, path)
 m.aggregatesLock.Unlock()

 // resolve symlinks
 path, err = m.resolve(path, false)
 if err != nil {
  return nil, err
 }

 // special case for root dir
 if path == "/" {
  return m.dirToFileInfo(&m.root, "/"), nil
 }

 // determine type and handle appropriately
 parentPath, baseName := pathSplit(path)
 dir, err := m.getDir(parentPath, false)
 if err != nil {
  return nil, err
 }
 subdir, subdirExists := dir.subdirs[baseName]
 if subdirExists {
  return m.dirToFileInfo(subdir, path), nil
 }
 file, fileExists := dir.files[baseName]
 if fileExists {
  return m.fileToFileInfo(file, path), nil
 }
 link, linkExists := dir.symlinks[baseName]
 if linkExists {
  return m.linkToFileInfo(link, path), nil
 }
 // not found
 return nil, &os.PathError{
  Op:   "stat",
  Path: path,
  Err:  os.ErrNotExist,
 }
}

func (m *MockFs) Stat(path string) (stats os.FileInfo, err error) {
 // resolve symlinks
 path, err = m.resolve(path, true)
 if err != nil {
  return nil, err
 }

 return m.Lstat(path)
}

func (m *MockFs) InodeNumber(info os.FileInfo) (number uint64, err error) {
 mockInfo, ok := info.(*mockFileInfo)
 if ok {
  return mockInfo.inodeNumber, nil
 }
 return 0, fmt.Errorf("%v is not a mockFileInfo", info)
}
func (m *MockFs) DeviceNumber(info os.FileInfo) (number uint64, err error) {
 mockInfo, ok := info.(*mockFileInfo)
 if ok {
  return mockInfo.deviceNumber, nil
 }
 return 0, fmt.Errorf("%v is not a mockFileInfo", info)
}
func (m *MockFs) PermTime(info os.FileInfo) (when time.Time, err error) {
 mockInfo, ok := info.(*mockFileInfo)
 if ok {
  return mockInfo.permTime, nil
 }
 return time.Date(0000000, nil),
  fmt.Errorf("%v is not a mockFileInfo", info)
}

func (m *MockFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
 // update aggregates
 m.aggregatesLock.Lock()
 m.ReadDirCalls = append(m.ReadDirCalls, path)
 m.aggregatesLock.Unlock()

 // locate directory
 path, err = m.resolve(path, true)
 if err != nil {
  return nil, err
 }
 results := []DirEntryInfo{}
 dir, err := m.getDir(path, false)
 if err != nil {
  return nil, err
 }
 if dir.readErr != nil {
  return nil, &os.PathError{
   Op:   "read",
   Path: path,
   Err:  dir.readErr,
  }
 }
 // describe its contents
 for name, subdir := range dir.subdirs {
  dirInfo := m.dirToFileInfo(subdir, name)
  results = append(results, dirInfo)
 }
 for name, file := range dir.files {
  info := m.fileToFileInfo(file, name)
  results = append(results, info)
 }
 for name, link := range dir.symlinks {
  info := m.linkToFileInfo(link, name)
  results = append(results, info)
 }
 return results, nil
}

func (m *MockFs) Rename(sourcePath string, destPath string) error {
 // validate source parent exists
 sourcePath, err := m.resolve(sourcePath, false)
 if err != nil {
  return err
 }
 sourceParentPath := filepath.Dir(sourcePath)
 sourceParentDir, err := m.getDir(sourceParentPath, false)
 if err != nil {
  return err
 }
 if sourceParentDir == nil {
  return &os.PathError{
   Op:   "move",
   Path: sourcePath,
   Err:  os.ErrNotExist,
  }
 }
 if sourceParentDir.readErr != nil {
  return &os.PathError{
   Op:   "move",
   Path: sourcePath,
   Err:  sourceParentDir.readErr,
  }
 }

 // validate dest parent exists
 destPath, err = m.resolve(destPath, false)
 destParentPath := filepath.Dir(destPath)
 destParentDir, err := m.getDir(destParentPath, false)
 if err != nil {
  return err
 }
 if destParentDir == nil {
  return &os.PathError{
   Op:   "move",
   Path: destParentPath,
   Err:  os.ErrNotExist,
  }
 }
 if destParentDir.readErr != nil {
  return &os.PathError{
   Op:   "move",
   Path: destParentPath,
   Err:  destParentDir.readErr,
  }
 }
 // check the source and dest themselves
 sourceBase := filepath.Base(sourcePath)
 destBase := filepath.Base(destPath)

 file, sourceIsFile := sourceParentDir.files[sourceBase]
 dir, sourceIsDir := sourceParentDir.subdirs[sourceBase]
 link, sourceIsLink := sourceParentDir.symlinks[sourceBase]

 // validate that the source exists
 if !sourceIsFile && !sourceIsDir && !sourceIsLink {
  return &os.PathError{
   Op:   "move",
   Path: sourcePath,
   Err:  os.ErrNotExist,
  }

 }

 // validate the destination doesn't already exist as an incompatible type
 _, destWasFile := destParentDir.files[destBase]
 _, destWasDir := destParentDir.subdirs[destBase]
 _, destWasLink := destParentDir.symlinks[destBase]

 if destWasDir {
  return &os.PathError{
   Op:   "move",
   Path: destPath,
   Err:  errors.New("destination exists as a directory"),
  }
 }

 if sourceIsDir && (destWasFile || destWasLink) {
  return &os.PathError{
   Op:   "move",
   Path: destPath,
   Err:  errors.New("destination exists as a file"),
  }
 }

 if destWasFile {
  delete(destParentDir.files, destBase)
 }
 if destWasDir {
  delete(destParentDir.subdirs, destBase)
 }
 if destWasLink {
  delete(destParentDir.symlinks, destBase)
 }

 if sourceIsFile {
  destParentDir.files[destBase] = file
  delete(sourceParentDir.files, sourceBase)
 }
 if sourceIsDir {
  destParentDir.subdirs[destBase] = dir
  delete(sourceParentDir.subdirs, sourceBase)
 }
 if sourceIsLink {
  destParentDir.symlinks[destBase] = link
  delete(destParentDir.symlinks, sourceBase)
 }

 destParentDir.modTime = m.Clock.Time()
 sourceParentDir.modTime = m.Clock.Time()
 return nil
}

func (m *MockFs) newInodeNumber() uint64 {
 result := m.nextInodeNumber
 m.nextInodeNumber++
 return result
}

func (m *MockFs) WriteFile(filePath string, data []byte, perm os.FileMode) error {
 filePath, err := m.resolve(filePath, true)
 if err != nil {
  return err
 }
 parentPath := filepath.Dir(filePath)
 parentDir, err := m.getDir(parentPath, false)
 if err != nil || parentDir == nil {
  return &os.PathError{
   Op:   "write",
   Path: parentPath,
   Err:  os.ErrNotExist,
  }
 }
 if parentDir.readErr != nil {
  return &os.PathError{
   Op:   "write",
   Path: parentPath,
   Err:  parentDir.readErr,
  }
 }

 baseName := filepath.Base(filePath)
 _, exists := parentDir.files[baseName]
 if !exists {
  parentDir.modTime = m.Clock.Time()
  parentDir.files[baseName] = m.newFile()
 } else {
  readErr := parentDir.files[baseName].readErr
  if readErr != nil {
   return &os.PathError{
    Op:   "write",
    Path: filePath,
    Err:  readErr,
   }
  }
 }
 file := parentDir.files[baseName]
 file.bytes = data
 file.modTime = m.Clock.Time()
 return nil
}

func (m *MockFs) newFile() *mockFile {
 newFile := &mockFile{}
 newFile.inodeNumber = m.newInodeNumber()
 newFile.modTime = m.Clock.Time()
 newFile.permTime = newFile.modTime
 return newFile
}

func (m *MockFs) newDir() *mockDir {
 newDir := &mockDir{
  subdirs:  make(map[string]*mockDir, 0),
  files:    make(map[string]*mockFile, 0),
  symlinks: make(map[string]*mockLink, 0),
 }
 newDir.inodeNumber = m.newInodeNumber()
 newDir.modTime = m.Clock.Time()
 newDir.permTime = newDir.modTime
 return newDir
}

func (m *MockFs) newLink(target string) *mockLink {
 newLink := &mockLink{
  target: target,
 }
 newLink.inodeNumber = m.newInodeNumber()
 newLink.modTime = m.Clock.Time()
 newLink.permTime = newLink.modTime

 return newLink
}
func (m *MockFs) MkDirs(path string) error {
 _, err := m.getDir(path, true)
 return err
}

// getDir doesn't support symlinks
func (m *MockFs) getDir(path string, createIfMissing bool) (dir *mockDir, err error) {
 cleanedPath := filepath.Clean(path)
 if cleanedPath == "/" {
  return &m.root, nil
 }

 parentPath, leaf := pathSplit(cleanedPath)
 if len(parentPath) >= len(path) {
  return &m.root, nil
 }
 parent, err := m.getDir(parentPath, createIfMissing)
 if err != nil {
  return nil, err
 }
 if parent.readErr != nil {
  return nil, &os.PathError{
   Op:   "stat",
   Path: path,
   Err:  parent.readErr,
  }
 }
 childDir, dirExists := parent.subdirs[leaf]
 if !dirExists {
  if createIfMissing {
   // confirm that a file with the same name doesn't already exist
   _, fileExists := parent.files[leaf]
   if fileExists {
    return nil, &os.PathError{
     Op:   "mkdir",
     Path: path,
     Err:  os.ErrExist,
    }
   }
   // create this directory
   childDir = m.newDir()
   parent.subdirs[leaf] = childDir
   parent.modTime = m.Clock.Time()
  } else {
   return nil, &os.PathError{
    Op:   "stat",
    Path: path,
    Err:  os.ErrNotExist,
   }
  }
 }
 return childDir, nil

}

func (m *MockFs) Remove(path string) (err error) {
 path, err = m.resolve(path, false)
 parentPath, leaf := pathSplit(path)
 if len(leaf) == 0 {
  return fmt.Errorf("Cannot remove %v\n", path)
 }
 parentDir, err := m.getDir(parentPath, false)
 if err != nil {
  return err
 }
 if parentDir == nil {
  return &os.PathError{
   Op:   "remove",
   Path: path,
   Err:  os.ErrNotExist,
  }
 }
 if parentDir.readErr != nil {
  return &os.PathError{
   Op:   "remove",
   Path: path,
   Err:  parentDir.readErr,
  }
 }
 _, isDir := parentDir.subdirs[leaf]
 if isDir {
  return &os.PathError{
   Op:   "remove",
   Path: path,
   Err:  os.ErrInvalid,
  }
 }
 _, isLink := parentDir.symlinks[leaf]
 if isLink {
  delete(parentDir.symlinks, leaf)
 } else {
  _, isFile := parentDir.files[leaf]
  if !isFile {
   return &os.PathError{
    Op:   "remove",
    Path: path,
    Err:  os.ErrNotExist,
   }
  }
  delete(parentDir.files, leaf)
 }
 parentDir.modTime = m.Clock.Time()
 return nil
}

func (m *MockFs) Symlink(oldPath string, newPath string) (err error) {
 newPath, err = m.resolve(newPath, false)
 if err != nil {
  return err
 }

 newParentPath, leaf := pathSplit(newPath)
 newParentDir, err := m.getDir(newParentPath, false)
 if newParentDir.readErr != nil {
  return &os.PathError{
   Op:   "link",
   Path: newPath,
   Err:  newParentDir.readErr,
  }
 }
 if err != nil {
  return err
 }
 newParentDir.symlinks[leaf] = m.newLink(oldPath)
 return nil
}

func (m *MockFs) RemoveAll(path string) (err error) {
 path, err = m.resolve(path, false)
 if err != nil {
  return err
 }
 parentPath, leaf := pathSplit(path)
 if len(leaf) == 0 {
  return fmt.Errorf("Cannot remove %v\n", path)
 }
 parentDir, err := m.getDir(parentPath, false)
 if err != nil {
  return err
 }
 if parentDir == nil {
  return &os.PathError{
   Op:   "removeAll",
   Path: path,
   Err:  os.ErrNotExist,
  }
 }
 if parentDir.readErr != nil {
  return &os.PathError{
   Op:   "removeAll",
   Path: path,
   Err:  parentDir.readErr,
  }

 }
 _, isFile := parentDir.files[leaf]
 _, isLink := parentDir.symlinks[leaf]
 if isFile || isLink {
  return m.Remove(path)
 }
 _, isDir := parentDir.subdirs[leaf]
 if !isDir {
  if !isDir {
   return &os.PathError{
    Op:   "removeAll",
    Path: path,
    Err:  os.ErrNotExist,
   }
  }
 }

 delete(parentDir.subdirs, leaf)
 parentDir.modTime = m.Clock.Time()
 return nil
}

func (m *MockFs) SetReadable(path string, readable bool) error {
 var readErr error
 if !readable {
  readErr = os.ErrPermission
 }
 return m.SetReadErr(path, readErr)
}

func (m *MockFs) SetReadErr(path string, readErr error) error {
 path, err := m.resolve(path, false)
 if err != nil {
  return err
 }
 parentPath, leaf := filepath.Split(path)
 parentDir, err := m.getDir(parentPath, false)
 if err != nil {
  return err
 }
 if parentDir.readErr != nil {
  return &os.PathError{
   Op:   "chmod",
   Path: parentPath,
   Err:  parentDir.readErr,
  }
 }

 inode, err := m.getInode(parentDir, leaf)
 if err != nil {
  return err
 }
 inode.readErr = readErr
 inode.permTime = m.Clock.Time()
 return nil
}

func (m *MockFs) ClearMetrics() {
 m.ReadDirCalls = []string{}
 m.StatCalls = []string{}
}

func (m *MockFs) ViewId() (id string) {
 return m.viewId
}

func (m *MockFs) SetViewId(id string) {
 m.viewId = id
}
func (m *MockFs) SetDeviceNumber(deviceNumber uint64) {
 m.deviceNumber = deviceNumber
}

[Dauer der Verarbeitung: 0.23 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik