Skip to content

Commit f9c3172

Browse files
committed
find mount points using realpath
1 parent 576e9ae commit f9c3172

File tree

3 files changed

+22
-34
lines changed

3 files changed

+22
-34
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/spf13/pflag v1.0.5
1818
github.com/stretchr/testify v1.8.4
1919
github.com/umlx5h/go-runewidth v0.0.0-20240106112317-9bbbb3702d5f
20+
github.com/yookoala/realpath v1.0.0
2021
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
2122
golang.org/x/term v0.21.0
2223
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ github.com/umlx5h/go-runewidth v0.0.0-20240106112317-9bbbb3702d5f h1:T8MNFeOIelX
8989
github.com/umlx5h/go-runewidth v0.0.0-20240106112317-9bbbb3702d5f/go.mod h1:+aP7JKaGs4irGEvKbEMTjKb1uKLoRZKMrrUwdGzajsk=
9090
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
9191
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
92+
github.com/yookoala/realpath v1.0.0 h1:7OA9pj4FZd+oZDsyvXWQvjn5oBdcHRTV44PpdMSuImQ=
93+
github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE=
9294
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
9395
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
9496
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=

internal/xdg/trashdir.go

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/moby/sys/mountinfo"
1616
"github.com/umlx5h/gtrash/internal/env"
17+
"github.com/yookoala/realpath"
1718
)
1819

1920
type trashDirType string
@@ -238,55 +239,39 @@ func getAllMountpoints() ([]string, error) {
238239
return mountpoints, nil
239240
}
240241

241-
// Obtain a mount point associated with a file
242+
// Obtain a mount point associated with a file.
242243
// Same as df <PATH>
243244
func getMountpoint(path string) (string, error) {
244-
// get mountpoints from /proc/self/mountinfo on Linux
245-
// getfsstat(2) used on Mac (BSD)
246245

247-
fi, err := os.Lstat(path)
246+
// iterate over the parents of the real (without symlinks) path until we find a mount point
247+
248+
candidate, err := realpath.Realpath(path)
248249
if err != nil {
249250
return "", err
250251
}
251252

252-
fromInfo, ok := fi.Sys().(*syscall.Stat_t)
253-
if !ok {
254-
return "", fmt.Errorf("get stat(2) st_dev")
255-
}
256-
257-
// this list could contain duplicate (bind) mount paths for the filesystem we are looking for,
258-
// any one of them qualifies as $topdir
259-
mountpoints, err := mountinfo.GetMounts(func(i *mountinfo.Info) (skip bool, stop bool) {
260-
// skip bind mounts into subdirectories
261-
if i.Root != "/" {
262-
return true, false
263-
}
264-
265-
mi, err := os.Stat(i.Mountpoint)
266-
if err != nil {
267-
return true, false
253+
OUTER:
254+
for {
255+
// root is always mounted
256+
if candidate == string(os.PathSeparator) {
257+
slog.Debug("root mountpoint is detected", "path", path)
258+
break OUTER
268259
}
269260

270-
mountInfo, ok := mi.Sys().(*syscall.Stat_t)
271-
if !ok {
272-
return true, false
261+
if candidate == "." {
262+
// should not reached here
263+
// check to prevent busy loop
264+
return "", errors.New("mountpoint is '.'")
273265
}
274266

275-
if mountInfo.Dev != fromInfo.Dev {
276-
return true, false
267+
if mounted, err := mountinfo.Mounted(candidate); err == nil && mounted {
268+
break OUTER
277269
}
278270

279-
return false, false
280-
})
281-
if err != nil {
282-
return "", err
283-
}
284-
285-
if len(mountpoints) == 0 {
286-
return "", fmt.Errorf("no mount for device %d", fromInfo.Dev)
271+
candidate = filepath.Dir(candidate)
287272
}
288273

289-
return mountpoints[0].Mountpoint, nil
274+
return candidate, nil
290275
}
291276

292277
func useHomeTrash(path string) (sameFS bool, err error) {

0 commit comments

Comments
 (0)