Skip to content

Commit 4e18d1f

Browse files
Merge pull request #2071 from dfr/freebsd-exists
pkg/fileutils: fix Lexists on FreeBSD
2 parents 7908bb8 + a603753 commit 4e18d1f

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

pkg/fileutils/exists_freebsd.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package fileutils
2+
3+
import (
4+
"errors"
5+
"os"
6+
"syscall"
7+
8+
"golang.org/x/sys/unix"
9+
)
10+
11+
// Exists checks whether a file or directory exists at the given path.
12+
// If the path is a symlink, the symlink is followed.
13+
func Exists(path string) error {
14+
// It uses unix.Faccessat which is a faster operation compared to os.Stat for
15+
// simply checking the existence of a file.
16+
err := unix.Faccessat(unix.AT_FDCWD, path, unix.F_OK, 0)
17+
if err != nil {
18+
return &os.PathError{Op: "faccessat", Path: path, Err: err}
19+
}
20+
return nil
21+
}
22+
23+
// Lexists checks whether a file or directory exists at the given path.
24+
// If the path is a symlink, the symlink itself is checked.
25+
func Lexists(path string) error {
26+
// FreeBSD before 15.0 does not support the AT_SYMLINK_NOFOLLOW flag for
27+
// faccessat. In this case, the call to faccessat will return EINVAL and
28+
// we fall back to using Lstat.
29+
err := unix.Faccessat(unix.AT_FDCWD, path, unix.F_OK, unix.AT_SYMLINK_NOFOLLOW)
30+
if err != nil && errors.Is(err, syscall.EINVAL) {
31+
_, err = os.Lstat(path)
32+
}
33+
if err != nil {
34+
return &os.PathError{Op: "faccessat", Path: path, Err: err}
35+
}
36+
return nil
37+
}

pkg/fileutils/exists_unix.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//go:build !windows
2-
// +build !windows
1+
//go:build !windows && !freebsd
2+
// +build !windows,!freebsd
33

44
package fileutils
55

0 commit comments

Comments
 (0)