func (c *Cgroups) Remove(name string) error { errCpu := syscall.Rmdir(c.cpuacct + "/" + name) errMemory := syscall.Rmdir(c.memory + "/" + name) if errCpu != nil && errMemory != nil { return errCpu } return nil }
// TestMkdirRmdir creates and deletes a directory func TestMkdirRmdir(t *testing.T, plainDir string) { dir := plainDir + "/dir1" err := os.Mkdir(dir, 0777) if err != nil { t.Error(err) return } err = syscall.Rmdir(dir) if err != nil { t.Error(err) return } // Removing a non-empty dir should fail with ENOTEMPTY if os.Mkdir(dir, 0777) != nil { t.Error(err) return } f, err := os.Create(dir + "/file") if err != nil { t.Error(err) return } f.Close() err = syscall.Rmdir(dir) errno := err.(syscall.Errno) if errno != syscall.ENOTEMPTY { t.Errorf("Should have gotten ENOTEMPTY, go %v", errno) } if syscall.Unlink(dir+"/file") != nil { t.Error(err) return } if syscall.Rmdir(dir) != nil { t.Error(err) return } // We should also be able to remove a directory we do not have permissions to // read or write err = os.Mkdir(dir, 0000) if err != nil { t.Error(err) return } err = syscall.Rmdir(dir) if err != nil { // Make sure the directory can cleaned up by the next test run os.Chmod(dir, 0700) t.Error(err) return } }
func (fs *FS) Delete(id string) error { //dn := fs.of_id(id) a, b, c, d := SplitFN(id) an := fs.Prefix + "/" + a bn := an + "/" + b cn := bn + "/" + c dn := cn + "/" + d e := os.RemoveAll(dn) if e == nil { syscall.Rmdir(cn) syscall.Rmdir(bn) syscall.Rmdir(an) } return e }
func TestWriteFilePermissions(t *testing.T) { dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) fullPath := path.Join(dir, "tmp", "foo") wf := File{ Path: fullPath, RawFilePermissions: "0755", } if err := WriteFile(&wf); err != nil { t.Fatalf("Processing of WriteFile failed: %v", err) } fi, err := os.Stat(fullPath) if err != nil { t.Fatalf("Unable to stat file: %v", err) } if fi.Mode() != os.FileMode(0755) { t.Errorf("File has incorrect mode: %v", fi.Mode()) } }
func (file *File) unlink() error { // Remove whatever was there. // NOTE: We will generally require the // write lock to be held for this routine. if file.write_deleted { err := cleardelattr(file.write_path) if err != nil { return err } } var stat syscall.Stat_t err := syscall.Lstat(file.write_path, &stat) if err == nil { if stat.Mode&syscall.S_IFDIR != 0 { err = syscall.Rmdir(file.write_path) if err != nil { return err } } else { err = syscall.Unlink(file.write_path) if err != nil { return err } } } file.write_exists = false file.write_deleted = false return nil }
// Remove removes the named file or directory. // If there is an error, it will be of type *PathError. func Remove(name string) error { // System call interface forces us to know // whether name is a file or directory. // Try both: it is cheaper on average than // doing a Stat plus the right one. e := syscall.Unlink(name) if e == nil { return nil } e1 := syscall.Rmdir(name) if e1 == nil { return nil } // Both failed: figure out which error to return. // OS X and Linux differ on whether unlink(dir) // returns EISDIR, so can't use that. However, // both agree that rmdir(file) returns ENOTDIR, // so we can use that to decide which error is real. // Rmdir might also return ENOTDIR if given a bad // file path, like /etc/passwd/foo, but in that case, // both errors will be ENOTDIR, so it's okay to // use the error from unlink. if e1 != syscall.ENOTDIR { e = e1 } return &PathError{"remove", name, e} }
func cmd_rmdir(cmd *Interpreter) (ErrorLevel, error) { if len(cmd.Args) <= 1 { fmt.Println("Usage: rmdir [/s] DIRECTORIES...") return NOERROR, nil } s_option := false message := "%s: Rmdir Are you sure? [Yes/No/Quit] " errorcount := ErrorLevel(0) for _, arg1 := range cmd.Args[1:] { if arg1 == "/s" { s_option = true message = "%s : Delete Tree. Are you sure? [Yes/No/Quit] " continue } stat, statErr := os.Lstat(arg1) if statErr != nil { fmt.Fprintf(cmd.Stderr, "%s: %s\n", arg1, statErr) errorcount++ continue } if !stat.IsDir() { fmt.Fprintf(cmd.Stderr, "%s: not directory\n", arg1) errorcount++ continue } fmt.Fprintf(cmd.Stderr, message, arg1) ch := conio.GetCh() fmt.Fprintf(cmd.Stderr, "%c ", ch) switch ch { case 'y', 'Y': case 'q', 'Q': fmt.Fprintln(cmd.Stderr, "-> canceled all") return errorcount, nil default: fmt.Fprintln(cmd.Stderr, "-> canceled") continue } var err error if s_option { fmt.Fprintln(cmd.Stdout) err = dos.Truncate(arg1, func(path string, err error) bool { fmt.Fprintf(cmd.Stderr, "%s -> %s\n", path, err.Error()) return true }, cmd.Stdout) } else { err = syscall.Rmdir(arg1) } if err != nil { fmt.Fprintf(cmd.Stderr, "-> %s\n", err.Error()) errorcount++ } else { fmt.Fprintln(cmd.Stderr, "-> done.") } } return errorcount, nil }
// Create and delete a directory func testMkdirRmdir(t *testing.T, plainDir string) { dir := plainDir + "dir1" err := os.Mkdir(dir, 0777) if err != nil { t.Fatal(err) } err = syscall.Rmdir(dir) if err != nil { t.Fatal(err) } // Removing a non-empty dir should fail with ENOTEMPTY if os.Mkdir(dir, 0777) != nil { t.Fatal(err) } f, err := os.Create(dir + "/file") if err != nil { t.Fatal(err) } f.Close() err = syscall.Rmdir(dir) errno := err.(syscall.Errno) if errno != syscall.ENOTEMPTY { t.Errorf("Should have gotten ENOTEMPTY, go %v", errno) } if syscall.Unlink(dir+"/file") != nil { t.Fatal(err) } if syscall.Rmdir(dir) != nil { t.Fatal(err) } // We should also be able to remove a directory we do not have permissions to // read or write err = os.Mkdir(dir, 0000) if err != nil { t.Fatal(err) } err = syscall.Rmdir(dir) if err != nil { t.Fatal(err) } }
func (constor *Constor) Rmdir(header *fuse.InHeader, name string) (code fuse.Status) { constor.log("%d %s", header.NodeId, name) var stat syscall.Stat_t parentino := header.NodeId dirpath, err := constor.dentrymap.getPath(parentino) if err != nil { return fuse.ToStatus(err) } path := Path.Join(dirpath, name) if err := constor.Lstat(path, &stat); err != nil { return fuse.ToStatus(err) } li := constor.getLayer(path) if li == -1 { return fuse.EIO } pathlayer0 := Path.Join(constor.layers[0], path) if li == 0 { // FIXME: make sure the dir is not empty // err = os.RemoveAll(pathlayer0) err = syscall.Rmdir(pathlayer0) if err != nil { return fuse.ToStatus(err) } li = constor.getLayer(path) } if li > 0 { err := constor.createPath(dirpath) if err != nil { return fuse.ToStatus(err) } fd, err := syscall.Creat(pathlayer0, 0) if err != nil { return fuse.ToStatus(err) } syscall.Close(fd) err = constor.setdeleted(pathlayer0) if err != nil { return fuse.ToStatus(err) } } dentry, err := constor.dentrymap.findDentry(parentino, stat.Ino) if err != nil { return fuse.ToStatus(err) } constor.dentrymap.unhashDentry(dentry) return fuse.OK }
func TestWriteFileInvalidPermission(t *testing.T) { wf := WriteFile{ Path: "/tmp/foo", Content: "bar", Permissions: "pants", } dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) if err := ProcessWriteFile(dir, &wf); err == nil { t.Fatalf("Expected error to be raised when writing file with invalid permission") } }
func TestPlaceNetworkUnit(t *testing.T) { u := Unit{ Name: "50-eth0.network", Runtime: true, Content: `[Match] Name=eth47 [Network] Address=10.209.171.177/19 `, } dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) if _, err := PlaceUnit(dir, &u); err != nil { t.Fatalf("PlaceUnit failed: %v", err) } fullPath := path.Join(dir, "run", "systemd", "network", "50-eth0.network") fi, err := os.Stat(fullPath) if err != nil { t.Fatalf("Unable to stat file: %v", err) } if fi.Mode() != os.FileMode(0644) { t.Errorf("File has incorrect mode: %v", fi.Mode()) } contents, err := ioutil.ReadFile(fullPath) if err != nil { t.Fatalf("Unable to read expected file: %v", err) } expect := `[Match] Name=eth47 [Network] Address=10.209.171.177/19 ` if string(contents) != expect { t.Fatalf("File has incorrect contents '%s'.\nExpected '%s'", string(contents), expect) } }
func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) { if fs.isFiltered(relPath) { return fuse.EPERM } encPath, err := fs.getBackingPath(relPath) if err != nil { return fuse.ToStatus(err) } if !fs.args.DirIV { return fuse.ToStatus(os.Mkdir(encPath, os.FileMode(mode))) } // We need write and execute permissions to create gocryptfs.diriv origMode := mode mode = mode | 0300 // The new directory may take the place of an older one that is still in the cache fs.CryptFS.DirIVCacheEnc.Clear() // Create directory fs.dirIVLock.Lock() defer fs.dirIVLock.Unlock() err = os.Mkdir(encPath, os.FileMode(mode)) if err != nil { return fuse.ToStatus(err) } // Create gocryptfs.diriv inside err = cryptfs.WriteDirIV(encPath) if err != nil { // This should not happen cryptfs.Warn.Printf("Mkdir: WriteDirIV failed: %v", err) err2 := syscall.Rmdir(encPath) if err2 != nil { cryptfs.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2) } return fuse.ToStatus(err) } // Set permissions back to what the user wanted if origMode != mode { err = os.Chmod(encPath, os.FileMode(origMode)) if err != nil { cryptfs.Warn.Printf("Mkdir: Chmod failed: %v", err) } } return fuse.OK }
func TestWriteFileEncodedContent(t *testing.T) { wf := WriteFile{ Path: "/tmp/foo", Content: "", Encoding: "base64", } dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) if err := ProcessWriteFile(dir, &wf); err == nil { t.Fatalf("Expected error to be raised when writing file with encoding") } }
func TestWriteFileInvalidPermission(t *testing.T) { dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) wf := File{ Path: path.Join(dir, "tmp", "foo"), Content: "bar", RawFilePermissions: "pants", } if err := WriteFile(&wf); err == nil { t.Fatalf("Expected error to be raised when writing file with invalid permission") } }
func cmd_rmdir(cmd *interpreter.Interpreter) (interpreter.NextT, error) { if len(cmd.Args) <= 1 { fmt.Println("Usage: rmdir [/s] DIRECTORIES...") return interpreter.CONTINUE, nil } s_option := false message := "%s: Rmdir Are you sure? [Yes/No/Quit] " for _, arg1 := range cmd.Args[1:] { if arg1 == "/s" { s_option = true message = "%s : Delete Tree. Are you sure? [Yes/No/Quit] " continue } fmt.Fprintf(cmd.Stderr, message, arg1) ch := conio.GetCh() fmt.Fprintf(cmd.Stderr, "%c ", ch) switch ch { case 'y', 'Y': case 'q', 'Q': fmt.Fprintln(cmd.Stderr, "-> canceled all") return interpreter.CONTINUE, nil default: fmt.Fprintln(cmd.Stderr, "-> canceled") continue } var err error if s_option { fmt.Fprintln(cmd.Stdout) err = dos.Truncate(arg1, func(path string, err error) bool { fmt.Fprintf(cmd.Stderr, "%s -> %s\n", path, err.Error()) return true }, cmd.Stdout) } else { err = syscall.Rmdir(arg1) } if err != nil { fmt.Fprintf(cmd.Stderr, "-> %s\n", err.Error()) } else { fmt.Fprintln(cmd.Stderr, "-> done.") } } return interpreter.CONTINUE, nil }
func TestPlaceMountUnit(t *testing.T) { u := Unit{ Name: "media-state.mount", Runtime: false, Content: `[Mount] What=/dev/sdb1 Where=/media/state `, } dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) if _, err := PlaceUnit(dir, &u); err != nil { t.Fatalf("PlaceUnit failed: %v", err) } fullPath := path.Join(dir, "etc", "systemd", "system", "media-state.mount") fi, err := os.Stat(fullPath) if err != nil { t.Fatalf("Unable to stat file: %v", err) } if fi.Mode() != os.FileMode(0644) { t.Errorf("File has incorrect mode: %v", fi.Mode()) } contents, err := ioutil.ReadFile(fullPath) if err != nil { t.Fatalf("Unable to read expected file: %v", err) } expect := `[Mount] What=/dev/sdb1 Where=/media/state ` if string(contents) != expect { t.Fatalf("File has incorrect contents '%s'.\nExpected '%s'", string(contents), expect) } }
func Truncate(folder string, whenError func(string, error) bool, out io.Writer) error { attr, attrErr := GetFileAttributes(folder) if attrErr != nil { return fmt.Errorf("%s: %s", folder, attrErr) } if (attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0 { // Only not junction, delete files under folder. fd, fdErr := os.Open(folder) if fdErr != nil { return fdErr } fi, fiErr := fd.Readdir(-1) fd.Close() if fiErr != nil { return fiErr } for _, f := range fi { if f.Name() == "." || f.Name() == ".." { continue } fullpath := Join(folder, f.Name()) var err error if f.IsDir() { fmt.Fprintf(out, "%s\\\n", fullpath) err = Truncate(fullpath, whenError, out) } else { fmt.Fprintln(out, fullpath) SetFileAttributes(fullpath, FILE_ATTRIBUTE_NORMAL) err = syscall.Unlink(fullpath) } if err != nil { if whenError != nil && !whenError(fullpath, err) { return fmt.Errorf("%s: %s", fullpath, err.Error()) } } } } if err := syscall.Rmdir(folder); err != nil { return fmt.Errorf("%s: %s", folder, err.Error()) } return nil }
func compile(prog parse.Program, outfile string) int { tempdir, err := ioutil.TempDir("/tmp", "jikken") if err != nil { log.Println("could not create temporary directory:", err) return 1 } defer func() { _ = syscall.Rmdir(tempdir) }() llfile := tempdir + "/jikken.ll" if err = ioutil.WriteFile(llfile, llcode(prog), 0644); err != nil { log.Println("could not write temporary file:", err) return 1 } defer func() { _ = syscall.Unlink(llfile) }() sfile := tempdir + "/jikken.s" defer func() { _ = syscall.Unlink(sfile) }() llc := exec.Command("llc", llfile) llc.Stdout = os.Stdout llc.Stderr = os.Stderr if err = llc.Run(); err != nil { log.Println("llc failed:", err) return 1 } gcc := exec.Command("gcc", "-o", outfile, sfile) gcc.Stdout = os.Stdout gcc.Stderr = os.Stderr if err = gcc.Run(); err != nil { log.Println("gcc failed:", err) return 1 } return 0 }
func TestDetectRemote_NotFound(t *testing.T) { dir, err := ioutil.TempDir("", "") if err != nil { t.Error("failed to create tempdir:", err) } defer syscall.Rmdir(dir) remotes, err := DetectRemote(dir + "/not_found") if remotes != nil { t.Error("unexpected result:", remotes) } if err == nil { t.Error("error should be set") } re := regexp.MustCompile(`^chdir `) if re.MatchString(err.Error()) == false { t.Error("unexpected error", err) } }
func (fs *FS) mkdirWithIv(cPath string, mode uint32) error { // Between the creation of the directory and the creation of gocryptfs.diriv // the directory is inconsistent. Take the lock to prevent other readers // from seeing it. fs.dirIVLock.Lock() // The new directory may take the place of an older one that is still in the cache fs.nameTransform.DirIVCache.Clear() defer fs.dirIVLock.Unlock() err := os.Mkdir(cPath, os.FileMode(mode)) if err != nil { return err } // Create gocryptfs.diriv err = nametransform.WriteDirIV(cPath) if err != nil { err2 := syscall.Rmdir(cPath) if err2 != nil { tlog.Warn.Printf("mkdirWithIv: rollback failed: %v", err2) } } return err }
func TestWriteFileUnencodedContent(t *testing.T) { dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-") if err != nil { t.Fatalf("Unable to create tempdir: %v", err) } defer syscall.Rmdir(dir) fullPath := path.Join(dir, "tmp", "foo") wf := File{ Path: fullPath, Content: "bar", RawFilePermissions: "0644", } if err := WriteFile(&wf); err != nil { t.Fatalf("Processing of WriteFile failed: %v", err) } fi, err := os.Stat(fullPath) if err != nil { t.Fatalf("Unable to stat file: %v", err) } if fi.Mode() != os.FileMode(0644) { t.Errorf("File has incorrect mode: %v", fi.Mode()) } contents, err := ioutil.ReadFile(fullPath) if err != nil { t.Fatalf("Unable to read expected file: %v", err) } if string(contents) != "bar" { t.Fatalf("File has incorrect contents") } }
// - [email protected]:username/repo.git func TestDetectRemoteForBitBucket(t *testing.T) { dir, err := ioutil.TempDir("", "") if err != nil { t.Error("failed to create tempdir:", err) } defer syscall.Rmdir(dir) git := exec.Command("git", "init") git.Dir = dir if err := git.Run(); err != nil { t.Error("failed to run git init:", err) } git = exec.Command("git", "remote", "add", "origin", "[email protected]:username/repo.git") git.Dir = dir if err := git.Run(); err != nil { t.Error("failed to run git remote add :", err) } remotes, err := DetectRemote(dir) if err != nil { t.Error("error should be nil:", err) } if len(remotes) < 1 { t.Error("unexpected remotes count") } if remotes[0].Name != "origin" { t.Error("unexpected remote name", remotes[0].Name) } if remotes[0].Url != "[email protected]:username/repo.git" { t.Error("unexpected remote url", remotes[0].Url) } }
func (constor *Constor) Rename(input *fuse.RenameIn, oldName string, newName string) (code fuse.Status) { sendEntryNotify := false var inodedel *Inode oldParent := constor.inodemap.findInodePtr(input.NodeId) if oldParent == nil { constor.error("oldParent == nil") return fuse.ENOENT } newParent := constor.inodemap.findInodePtr(input.Newdir) if newParent == nil { constor.error("newParent == nil") return fuse.ENOENT } if err := constor.copyup(newParent); err != nil { constor.error("copyup failed for %s - %s", newParent.id, err) return fuse.EIO } newParentPath := constor.getPath(0, newParent.id) newentrypath := Path.Join(newParentPath, newName) constor.log("%s %s %s %s", oldParent.id, oldName, newParent.id, newName) // remove any entry that existed in the newName's place if iddel, err := constor.getid(-1, newParent.id, newName); err == nil { if inodedel = constor.inodemap.findInodeId(iddel); inodedel != nil { if inodedel.layer == 0 { linkcnt, err := constor.declinkscnt(inodedel.id) if err != nil { constor.error("declinkscnt %s : %s", inodedel.id, err) return fuse.ToStatus(err) } if linkcnt == 0 { path := constor.getPath(0, iddel) fi, err := os.Lstat(path) if err != nil { constor.error("Lstat failed on %s", path) return fuse.ToStatus(err) } if fi.IsDir() { // FIXME: take care of this situation constor.error("path is a directory") return fuse.Status(syscall.EEXIST) } if err := syscall.Unlink(path); err != nil { constor.error("Unable to remove %s", path) return fuse.ToStatus(err) } inodedel.layer = -1 } } stat := syscall.Stat_t{} // FIXME do copyup and declinkscnt if err := syscall.Lstat(newentrypath, &stat); err == nil { fi, err := os.Lstat(newentrypath) if err != nil { constor.error("Lstat failed on %s", newentrypath) return fuse.ToStatus(err) } if fi.IsDir() { // FIXME: take care of this situation constor.error("path is a directory") return fuse.Status(syscall.EEXIST) } if err := syscall.Unlink(newentrypath); err != nil { constor.error("Unable to remove %s", newentrypath) return fuse.ToStatus(err) } } // inodedel.parentPtr = input.Newdir // inodedel.name = newName sendEntryNotify = true // constor.ms.DeleteNotify(input.Newdir, uint64(uintptr(unsafe.Pointer(inodedel))), newName) // constor.ms.EntryNotify(input.Newdir, newName) } else { constor.error("inodedel == nil for %s %s", newParent.id, newName) return fuse.EIO } } // remove any deleted placeholder if constor.isdeleted(newentrypath, nil) { if err := syscall.Unlink(newentrypath); err != nil { constor.error("Unlink %s : %s", newentrypath, err) return fuse.ToStatus(err) } } oldid, err := constor.getid(-1, oldParent.id, oldName) if err != nil { constor.error("getid error %s %s", oldParent.id, oldName) return fuse.ToStatus(err) } oldinode := constor.inodemap.findInodeId(oldid) if oldinode == nil { constor.error("oldinode == nil for %s", oldid) return fuse.ENOENT } path := constor.getPath(oldinode.layer, oldid) fi, err := os.Lstat(path) if err != nil { constor.error("Lstat %s", path) return fuse.ToStatus(err) } oldParentPath := constor.getPath(0, oldParent.id) oldentrypath := Path.Join(oldParentPath, oldName) oldstat := syscall.Stat_t{} if err := syscall.Lstat(oldentrypath, &oldstat); err == nil { if fi.IsDir() { if err := syscall.Rmdir(oldentrypath); err != nil { constor.error("Rmdir %s : %s", oldentrypath, err) return fuse.ToStatus(err) } } else { if err := syscall.Unlink(oldentrypath); err != nil { constor.error("Unlink %s : %s", oldentrypath, err) return fuse.ToStatus(err) } } } if _, err := constor.getid(-1, oldParent.id, oldName); err == nil { constor.setdeleted(oldentrypath) } if fi.Mode()&os.ModeSymlink == os.ModeSymlink { err = os.Symlink("placeholder", newentrypath) if err != nil { constor.error("Symlink %s : %s", newentrypath, err) return fuse.ToStatus(err) } } else if fi.Mode()&os.ModeDir == os.ModeDir { err := os.Mkdir(newentrypath, fi.Mode()) if err != nil { constor.error("Mkdir %s : %s", newentrypath, err) return fuse.ToStatus(err) } } else { fd, err := syscall.Creat(newentrypath, uint32(fi.Mode())) if err != nil { constor.error("create %s : %s", newentrypath, err) return fuse.ToStatus(err) } syscall.Close(fd) } id := constor.setid(newentrypath, oldid) if id == "" { constor.error("setid %s : %s", newentrypath, err) return fuse.EIO } if sendEntryNotify { go func() { // FIXME: is this needed? constor.ms.DeleteNotify(input.Newdir, uint64(uintptr(unsafe.Pointer(inodedel))), newName) constor.ms.DeleteNotify(input.NodeId, uint64(uintptr(unsafe.Pointer(oldinode))), oldName) }() } return fuse.OK }
func (fs *KakigooriFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) { fullPath := fs.GetPath(name) go event.Notify(event.Rmdir, fullPath) return fuse.ToStatus(syscall.Rmdir(fullPath)) }
// This test is inspired on xfstest, t_dir_offset2.c func TestReaddirPlusSeek(t *testing.T) { tc := NewTestCase(t) defer tc.Cleanup() var names []string for i := 0; i < 20; i++ { names = append(names, fmt.Sprintf("abcd%d", i)) } for _, n := range names { if err := os.MkdirAll(filepath.Join(tc.origSubdir, n), 0755); err != nil { t.Fatalf("Mkdir failed: %v", err) } } fd, err := syscall.Open(tc.mountSubdir, syscall.O_RDONLY, 0755) if err != nil { t.Fatalf("Open(%q): %v", tc.mountSubdir, err) } defer syscall.Close(int(fd)) // store offsets type entryOff struct { ino uint64 off int64 } previous := map[int]entryOff{} var bufdata [1024]byte for { buf := bufdata[:] n, err := syscall.ReadDirent(fd, buf) if err != nil { t.Fatalf("ReadDirent: %v", err) } if n == 0 { break } buf = buf[:n] for _, d := range parseDirents(buf) { if d.name == "." || d.name == ".." { continue } i := len(previous) previous[i] = entryOff{d.ino, d.off} } } for i := len(previous) - 1; i >= 0; i-- { var off int64 if i > 0 { off = previous[i-1].off } if _, err := syscall.Seek(fd, off, 0); err != nil { t.Fatalf("Seek %v", err) } buf := bufdata[:] n, err := syscall.ReadDirent(fd, buf) if err != nil { t.Fatalf("readdir after seek %d: %v", i, err) } if n == 0 { t.Fatalf("no dirent after seek to %d", i) } ds := parseDirents(buf[:n]) if ds[0].ino != previous[i].ino { t.Errorf("got ino %d, want %d", ds[0].ino, previous[i].ino) } } // Delete has a forget as side-effect: make sure we get the lookup counts correct. for _, n := range names { full := filepath.Join(tc.mountSubdir, n) if err := syscall.Rmdir(full); err != nil { t.Fatalf("Rmdir(%q): %v", n, err) } } }
func (fs *LoopbackFileSystem) Rmdir(name string, context *Context) (code Status) { return ToStatus(syscall.Rmdir(fs.GetPath(name))) }
func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) { encPath, err := fs.getBackingPath(name) if err != nil { return fuse.ToStatus(err) } if !fs.args.DirIV { return fuse.ToStatus(syscall.Rmdir(encPath)) } // If the directory is not empty besides gocryptfs.diriv, do not even // attempt the dance around gocryptfs.diriv. fd, err := os.Open(encPath) if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES { // We need permission to read and modify the directory cryptfs.Debug.Printf("Rmdir: handling EACCESS") fi, err2 := os.Stat(encPath) if err2 != nil { cryptfs.Debug.Printf("Rmdir: Stat: %v", err2) return fuse.ToStatus(err2) } origMode := fi.Mode() newMode := origMode | 0700 err2 = os.Chmod(encPath, newMode) if err2 != nil { cryptfs.Debug.Printf("Rmdir: Chmod failed: %v", err2) return fuse.ToStatus(err) } defer func() { if code != fuse.OK { // Undo the chmod if removing the directory failed err3 := os.Chmod(encPath, origMode) if err3 != nil { cryptfs.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2) } } }() // Retry open fd, err = os.Open(encPath) } if err != nil { cryptfs.Debug.Printf("Rmdir: Open: %v", err) return fuse.ToStatus(err) } list, err := fd.Readdirnames(10) fd.Close() if err != nil { cryptfs.Debug.Printf("Rmdir: Readdirnames: %v", err) return fuse.ToStatus(err) } if len(list) > 1 { return fuse.ToStatus(syscall.ENOTEMPTY) } else if len(list) == 0 { cryptfs.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion") return fuse.ToStatus(syscall.Rmdir(encPath)) } // Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ" dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME) parentDir := filepath.Dir(encPath) tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptfs.RandUint64()) tmpDirivPath := filepath.Join(parentDir, tmpName) cryptfs.Debug.Printf("Rmdir: Renaming %s to %s", cryptfs.DIRIV_FILENAME, tmpDirivPath) // The directory is in an inconsistent state between rename and rmdir. Protect against // concurrent readers. fs.dirIVLock.Lock() defer fs.dirIVLock.Unlock() err = os.Rename(dirivPath, tmpDirivPath) if err != nil { cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", cryptfs.DIRIV_FILENAME, tmpDirivPath, err) return fuse.ToStatus(err) } // Actual Rmdir err = syscall.Rmdir(encPath) if err != nil { // This can happen if another file in the directory was created in the // meantime, undo the rename err2 := os.Rename(tmpDirivPath, dirivPath) if err2 != nil { cryptfs.Warn.Printf("Rmdir: Rename rollback failed: %v", err2) } return fuse.ToStatus(err) } // Delete "gocryptfs.diriv.rmdir.INODENUMBER" err = syscall.Unlink(tmpDirivPath) if err != nil { cryptfs.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err) } // The now-deleted directory may have been in the DirIV cache. Clear it. fs.CryptFS.DirIVCacheEnc.Clear() return fuse.OK }
func (me *LoopbackFileSystem) Rmdir(name string) (code Status) { return Status(syscall.Rmdir(me.GetPath(name))) }
func (fs *loopbackFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) { return fuse.ToStatus(syscall.Rmdir(fs.GetPath(name))) }
// Rmdir implements pathfs.FileSystem func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) { cPath, err := fs.getBackingPath(path) if err != nil { return fuse.ToStatus(err) } if fs.args.PlaintextNames { err = syscall.Rmdir(cPath) return fuse.ToStatus(err) } parentDir := filepath.Dir(cPath) parentDirFd, err := os.Open(parentDir) if err != nil { return fuse.ToStatus(err) } defer parentDirFd.Close() cName := filepath.Base(cPath) dirfdRaw, err := syscallcompat.Openat(int(parentDirFd.Fd()), cName, syscall.O_RDONLY, 0) if err == syscall.EACCES { // We need permission to read and modify the directory tlog.Debug.Printf("Rmdir: handling EACCESS") // TODO use syscall.Fstatat once it is available in Go var fi os.FileInfo fi, err = os.Lstat(cPath) if err != nil { tlog.Debug.Printf("Rmdir: Stat: %v", err) return fuse.ToStatus(err) } origMode := fi.Mode() // TODO use syscall.Chmodat once it is available in Go err = os.Chmod(cPath, origMode|0700) if err != nil { tlog.Debug.Printf("Rmdir: Chmod failed: %v", err) return fuse.ToStatus(err) } // Retry open var st syscall.Stat_t syscall.Lstat(cPath, &st) dirfdRaw, err = syscallcompat.Openat(int(parentDirFd.Fd()), cName, syscall.O_RDONLY, 0) // Undo the chmod if removing the directory failed defer func() { if code != fuse.OK { err = os.Chmod(cPath, origMode) if err != nil { tlog.Warn.Printf("Rmdir: Chmod rollback failed: %v", err) } } }() } if err != nil { tlog.Debug.Printf("Rmdir: Open: %v", err) return fuse.ToStatus(err) } dirfd := os.NewFile(uintptr(dirfdRaw), cName) defer dirfd.Close() children, err := dirfd.Readdirnames(10) if err == nil { // If the directory is not empty besides gocryptfs.diriv, do not even // attempt the dance around gocryptfs.diriv. if len(children) > 1 { return fuse.ToStatus(syscall.ENOTEMPTY) } // Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ" tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptocore.RandUint64()) tlog.Debug.Printf("Rmdir: Renaming %s to %s", nametransform.DirIVFilename, tmpName) // The directory is in an inconsistent state between rename and rmdir. // Protect against concurrent readers. fs.dirIVLock.Lock() defer fs.dirIVLock.Unlock() err = syscallcompat.Renameat(int(dirfd.Fd()), nametransform.DirIVFilename, int(parentDirFd.Fd()), tmpName) if err != nil { tlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", nametransform.DirIVFilename, tmpName, err) return fuse.ToStatus(err) } // Actual Rmdir // TODO Use syscall.Unlinkat with the AT_REMOVEDIR flag once it is available // in Go err = syscall.Rmdir(cPath) if err != nil { // This can happen if another file in the directory was created in the // meantime, undo the rename err2 := syscallcompat.Renameat(int(parentDirFd.Fd()), tmpName, int(dirfd.Fd()), nametransform.DirIVFilename) if err != nil { tlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2) } return fuse.ToStatus(err) } // Delete "gocryptfs.diriv.rmdir.XYZ" err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName) if err != nil { tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err) } } else if err == io.EOF { // The directory is empty tlog.Warn.Printf("Rmdir: %q: gocryptfs.diriv is missing", cPath) err = syscall.Rmdir(cPath) if err != nil { return fuse.ToStatus(err) } } else { tlog.Warn.Printf("Rmdir: Readdirnames: %v", err) return fuse.ToStatus(err) } // Delete .name file if nametransform.IsLongContent(cName) { nametransform.DeleteLongName(parentDirFd, cName) } // The now-deleted directory may have been in the DirIV cache. Clear it. fs.nameTransform.DirIVCache.Clear() return fuse.OK }