Skip to content

Instantly share code, notes, and snippets.

@hamrickdavid
Created October 9, 2011 21:35
Show Gist options
  • Save hamrickdavid/1274228 to your computer and use it in GitHub Desktop.
Save hamrickdavid/1274228 to your computer and use it in GitHub Desktop.
Methods of Reloading Config Files
FileSystemWatch* watcher = [[FileSystemWatch alloc] init];
[watcher watchFileAtPath:@"path/to/config.plist" target:self action:@selector(fileChanged:)];
...
- (void)fileChanged:(FileSystemWatch*)watcher
{
NSLog(@"File changed, time to reload");
}
[watcher stopWatching];
[watcher release];
#import <Foundation/Foundation.h>
@interface FileSystemWatch : NSObject
- (void)watchFileAtPath:(NSString*)path target:(id)target action:(SEL)action;
- (void)stopWatching;
@end
#import "FileSystemWatch.h"
#include <sys/event.h>
#include <sys/time.h>
#include <fcntl.h>
@interface FileSystemWatch ()
@property (nonatomic,retain) NSString* path;
@property (nonatomic,assign) id target;
@property (nonatomic,assign) SEL action;
@property (nonatomic,assign) int fildes;
@property (nonatomic,assign) int kq;
@property (nonatomic,retain) NSThread* watchThread;
@end
@implementation FileSystemWatch
@synthesize path = _path;
@synthesize target = _target;
@synthesize action = _action;
@synthesize fildes = _fildes;
@synthesize kq = _kq;
@synthesize watchThread = _watchThread;
- (void)dealloc
{
[_path release], _path = nil;
[_watchThread release], _watchThread = nil;
[super dealloc];
}
- (void)watchFileAtPath:(NSString*)path target:(id)target action:(SEL)action
{
self.path = path;
self.target = target;
self.action = action;
self.fildes = open([self.path UTF8String], O_RDONLY);
if(self.fildes <= 0)
{
return;
}
self.kq = kqueue();
self.watchThread = [[[NSThread alloc] initWithTarget:self selector:@selector(watchInBackground) object:nil] autorelease];
[self.watchThread start];
}
- (void)stopWatching
{
close(self.kq);
close(self.fildes);
[self.watchThread cancel];
}
- (void)watchInBackground
{
int status;
struct kevent change;
struct kevent event;
EV_SET(&change, self.fildes, EVFILT_VNODE,
EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
0, 0);
while(status > 0)
{
status = kevent(self.kq, &change, 1, &event, 1, NULL);
if(status > 0)
{
if([self.target respondsToSelector:self.action])
[self.target performSelectorOnMainThread:self.action withObject:self waitUntilDone:YES];
}
}
close(self.kq);
close(self.fildes);
}
@end
#include <sys/event.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char** argv)
{
int fildes;
int kq;
int status;
struct kevent change;
struct kevent event;
kq = kqueue();
fildes = open("test.plist", O_RDONLY);
if(fildes <= 0)
{
printf("No such file...\n");
return -1;
}
EV_SET(&change, fildes, EVFILT_VNODE,
EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
0, 0);
for(;;)
{
status = kevent(kq, &change, 1, &event, 1, NULL);
if(status > 0)
{
printf("Reload config file\n");
}
}
close(kq);
close(fildes);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char** argv)
{
struct stat buffer;
int status;
int fildes = open("test.plist",O_RDONLY);
time_t startTime = 0;
if(fildes <= 0)
{
printf("No such file...\n");
return -1;
}
for(;;)
{
status = fstat(fildes,&buffer);
if(startTime != buffer.st_atime)
{
startTime = buffer.st_atime;
printf("Reload Config File\n");
}
usleep(100*1000); //Sleep for 0.1 seconds
}
close(fildes);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment