mapsize 1.2.0: permanent delete and in-map reveal when headless
On a headless Linux or BSD system (no DISPLAY or WAYLAND_DISPLAY) nothing empties the freedesktop trash, so trashing never freed space. There, d now deletes permanently after an explicit confirmation, checking owner and type against the scan and removing through an os.Root on the parent so a swapped symlink cannot redirect it. o shows the folder in the map instead of launching a file manager. Desktop sessions, macOS and Windows are unchanged.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
//go:build unix
|
||||
|
||||
package platform
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Delete permanently removes path (recursively for a directory) if it still
|
||||
// matches want. The check and the removal both go through an os.Root on the
|
||||
// parent directory, so a symlink swapped in since the scan cannot redirect
|
||||
// the removal outside it.
|
||||
func Delete(path string, want Expect) error {
|
||||
if err := checkAbs(path); err != nil {
|
||||
return err
|
||||
}
|
||||
dir, base := filepath.Dir(path), filepath.Base(path)
|
||||
root, err := os.OpenRoot(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer root.Close()
|
||||
fi, err := root.Lstat(base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fi.Sys().(*syscall.Stat_t).Uid != want.UID || fi.Mode()&fs.ModeType != want.Mode&fs.ModeType {
|
||||
return errors.New("item changed since the scan (owner or type differs); rescan first")
|
||||
}
|
||||
return root.RemoveAll(base)
|
||||
}
|
||||
Reference in New Issue
Block a user