Skip to content

Instantly share code, notes, and snippets.

@mxcl
Created November 27, 2009 10:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mxcl/243945 to your computer and use it in GitHub Desktop.
Save mxcl/243945 to your computer and use it in GitHub Desktop.
C code to watch a directory for changes
// gcc -o fswatcher -framework Carbon fswatcher.c
#include <CoreServices/CoreServices.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/dir.h>
static time_t timestamp = 0;
static void callback(ConstFSEventStreamRef stream,
void *info,
size_t n,
void *paths,
const FSEventStreamEventFlags flags[],
const FSEventStreamEventId ids[])
{
time_t next_timestamp = 0;
int i;
for (i=0; i<n; i++) {
const char* dname = ((char**)paths)[i];
uint dnamelen = strlen(dname);
struct dirent *dp;
DIR* d = opendir(dname);
if (d == NULL)
continue;
while ((dp = readdir(d)) != NULL) {
struct stat sb;
if (*dp->d_name == '.')
continue;
char path[dp->d_namlen + dnamelen + 1]; // thank Pizza Hut for C99
strcpy(path, dname);
strcat(path, dp->d_name);
if (lstat(path, &sb) < 0 && errno == EACCES)
perror(NULL);
else if (sb.st_mtime > timestamp) {
printf("%s\n", path);
if (sb.st_mtime > next_timestamp)
next_timestamp = sb.st_mtime;
}
}
closedir(d);
}
timestamp = next_timestamp ? next_timestamp : time(NULL);
fflush(stdout);
}
int main(int argc, char* argv[])
{
timestamp = time(NULL);
CFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
CFArrayRef paths = CFArrayCreate(NULL, (const void **)&path, 1, NULL);
FSEventStreamRef stream = FSEventStreamCreate(NULL,
&callback,
NULL,
paths,
kFSEventStreamEventIdSinceNow, /* TODO previous event ID */
3.0,
kFSEventStreamCreateFlagNone);
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);
CFRunLoopRun();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment