Skip to content

Do not force absolute Paths #49

@philjb

Description

@philjb

fsevents @ 1055680

Which version of macOS are you using?

ProductName:    Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H1217

Please describe the issue that occurred.

FSEvents api supports two different ways of starting an event stream:

  1. Uses a device id and function call FSEventStreamCreateRelativeToDevice which is expecting paths to be relative to the mount point of the device. This is called the per-disk event stream in the docs. The example/main.go uses this approach since it uses a non-zero device id. See the documentation here specifically about param pathsToWatchRelativeToDevice
pathsToWatchRelativeToDevice
A CFArray of CFStringRefs, each specifying a relative path to a directory on the device identified by the dev parameter. The paths should be relative to the root of the device. For example, if a volume "MyData" is mounted at "/Volumes/MyData" and you want to watch "/Volumes/MyData/Pictures/July", specify a path string of "Pictures/July". To watch the root of a volume pass a path of "" (the empty string).
  1. The alternative is with function FSEventStreamCreate which is expecting absolute paths. This is the "per-host" event stream constructor. fsevents uses this approach if the Device in the EventStream struct is zero. While the docs are ambiguous, on my system, the "per-host" approach only works with absolute paths.
pathsToWatch
A CFArray of CFStringRefs, each specifying a path to a directory, signifying the root of a filesystem hierarchy to be watched for modifications.

However, wrap.go/createPaths() transforms all paths in an EventStream struct to absolute paths at

fsevents/wrap.go

Lines 154 to 158 in f721bd2

func createPaths(paths []string) (C.CFArrayRef, error) {
cPaths := C.ArrayCreateMutable(C.int(len(paths)))
var errs []error
for _, path := range paths {
p, err := filepath.Abs(path)

This prevents using the "per-disk" mode for all volumes except the root volume at /.

Are you able to reproduce the issue? Please provide steps to reproduce and a code sample if possible.

Yes.

  1. Create a new Volume on OSX (I use APFS) mounted at /Volumes/fsevents-repo
  2. Use the example/main.go program with path /Volumes/fsevents-repo (the only change)
  3. go run ./example/main.go
  4. touch /Volumes/fsevents-repo/testfile and observe there is no event reports.
  5. Now, change wrap.go/createPaths to using
	for _, path := range paths {
		p := path
		cpath := C.CString(p)

and repeat the steps above.

PR coming shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions