aboutsummaryrefslogtreecommitdiff
path: root/filesystem
diff options
context:
space:
mode:
Diffstat (limited to 'filesystem')
-rw-r--r--filesystem/path.go6
-rw-r--r--filesystem/path_test.go27
2 files changed, 33 insertions, 0 deletions
diff --git a/filesystem/path.go b/filesystem/path.go
index b9b403d..274dc0a 100644
--- a/filesystem/path.go
+++ b/filesystem/path.go
@@ -78,6 +78,12 @@ func isRegularFile(path string) bool {
return err == nil && info.Mode().IsRegular()
}
+// HaveReadAccessTo returns true if the process has read access to a file or
+// directory, without actually opening it.
+func HaveReadAccessTo(path string) bool {
+ return unix.Access(path, unix.R_OK) == nil
+}
+
// DeviceNumber represents a combined major:minor device number.
type DeviceNumber uint64
diff --git a/filesystem/path_test.go b/filesystem/path_test.go
index eef5ce3..4152037 100644
--- a/filesystem/path_test.go
+++ b/filesystem/path_test.go
@@ -20,6 +20,8 @@ package filesystem
import (
"fmt"
+ "io/ioutil"
+ "os"
"testing"
)
@@ -52,3 +54,28 @@ func TestDeviceNumber(t *testing.T) {
t.Error("Should have failed to parse invalid device number")
}
}
+
+func TestHaveReadAccessTo(t *testing.T) {
+ file, err := ioutil.TempFile("", "fscrypt_test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ file.Close()
+ defer os.Remove(file.Name())
+
+ testCases := map[os.FileMode]bool{
+ 0444: true,
+ 0400: true,
+ 0000: false,
+ 0040: false, // user bits take priority in Linux
+ 0004: false, // user bits take priority in Linux
+ }
+ for mode, readable := range testCases {
+ if err := os.Chmod(file.Name(), mode); err != nil {
+ t.Error(err)
+ }
+ if HaveReadAccessTo(file.Name()) != readable {
+ t.Errorf("Expected readable=%v on mode=0%03o", readable, mode)
+ }
+ }
+}