Question

On OSX 10.8.x, I am using FSEvents to detect changes in a directory. The problem is that when a file is copied via sftp, the FSEvents callback is not called.
When I am using cp to copy a file (or touch to simulate a change), the callback is called. Am I doing something stupid ? Is sshd using some sort of low level API to create the file ? Should I file a bug to Apple ?

eventQueue = dispatch_queue_create(EVENT_QUEUE_NAME, DISPATCH_QUEUE_SERIAL);

//Watch the data/apns directory (for .json files)
NSString *pathToWatch = ...
NSArray  *pathsToWatch = @[pathToWatch];
CFAbsoluteTime latency = 1.0; /* Latency in seconds */

// Create the FileSystem events stream, passing in a callback
streamRef = FSEventStreamCreate(NULL,
                                &fscallback,
                                NULL,
                                (__bridge CFArrayRef)(pathsToWatch),
                                kFSEventStreamEventIdSinceNow,
                                latency,
                                kFSEventStreamCreateFlagIgnoreSelf);
if (streamRef)
{
    FSEventStreamSetDispatchQueue(streamRef, eventQueue);
    if (NO == FSEventStreamStart(streamRef))
    {
        DDLogError(@"FSEventStreamStart error");
    }
    else
    {
        DDLogError(@"FSEventStreamStart ok");
    }
}
else
{
    DDLogError(@"FSEventStreamCreate error");
}

I am using internal-sftp in the sshd config:

...
Subsystem sftp internal-sftp

Match Group users
PasswordAuthentication yes
AllowTCPForwarding no
X11Forwarding no
ForceCommand internal-sftp
Match User user
ChrootDirectory /vhosts/web/user
Was it helpful?

Solution

No, you're not doing anything wrong. The problem relates to your use of a chroot; I was able to reproduce this without involving sshd at all, just by running touch in a chroot.

FSEvents is recording the events as occurring on the path in the chroot, e.g., /foo rather than /vhosts/web/user/foo.

This is almost certainly an OS X bug; whether you're going to get Apple to fix it any time soon is another matter. Your best bet is probably to use Apple's sandboxing (run sftp-server with sandbox-exec) rather than a chroot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top