pbind 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +0,0 @@
1
- //
2
- // SGDirObserver.h
3
- // DirectoryObserver
4
- //
5
- // Copyright (c) 2011 Simon Grätzer.
6
- //
7
-
8
- #include <targetconditionals.h>
9
-
10
- #if (DEBUG && TARGET_IPHONE_SIMULATOR)
11
-
12
- #import <Foundation/Foundation.h>
13
-
14
- @interface SGDirWatchdog : NSObject
15
-
16
- @property (readonly, nonatomic) NSString *path;
17
- @property (copy, nonatomic) void (^update)(void);
18
-
19
- + (NSString *)documentsPath;
20
- + (id)watchtdogOnDocumentsDir:(void (^)(void))update;
21
-
22
- - (id)initWithPath:(NSString *)path update:(void (^)(void))update;
23
-
24
- - (void)start;
25
- - (void)stop;
26
-
27
- @end
28
-
29
- #endif
@@ -1,163 +0,0 @@
1
- //
2
- // SGDirObserver.m
3
- // DirectoryObserver
4
- //
5
- // Copyright (c) 2011 Simon Grätzer.
6
- //
7
-
8
- #import "SGDirWatchdog.h"
9
-
10
- #if (DEBUG && TARGET_IPHONE_SIMULATOR)
11
-
12
- #import <fcntl.h>
13
- #import <unistd.h>
14
- #import <sys/event.h>
15
-
16
- @interface SGDirWatchdog ()
17
- @property (nonatomic, readonly) CFFileDescriptorRef kqRef;
18
- - (void)kqueueFired;
19
- @end
20
-
21
-
22
- static void KQCallback(CFFileDescriptorRef kqRef, CFOptionFlags callBackTypes, void *info) {
23
- // Pick up the object passed in the "info" member of the CFFileDescriptorContext passed to CFFileDescriptorCreate
24
- SGDirWatchdog* obj = (__bridge SGDirWatchdog*) info;
25
-
26
- if ([obj isKindOfClass:[SGDirWatchdog class]] && // If we can call back to the proper sort of object ...
27
- (kqRef == obj.kqRef) && // and the FD that issued the CB is the expected one ...
28
- (callBackTypes == kCFFileDescriptorReadCallBack) ) // and we're processing the proper sort of CB ...
29
- {
30
- [obj kqueueFired]; // Invoke the instance's CB handler
31
- }
32
- }
33
-
34
- @implementation SGDirWatchdog {
35
- int _dirFD;
36
- CFFileDescriptorRef _kqRef;
37
- }
38
-
39
- + (NSString *)documentsPath {
40
- NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
41
-
42
- return documentsPaths[0]; // Path to the application's "Documents" directory
43
- }
44
-
45
- + (id)watchtdogOnDocumentsDir:(void (^)(void))update; {
46
- return [[SGDirWatchdog alloc]initWithPath:[self documentsPath] update:update];
47
- }
48
-
49
-
50
- - (id)initWithPath:(NSString *)path update:(void (^)(void))update; {
51
- if ((self = [super init])) {
52
- _path = path;
53
- _update = [update copy];
54
- }
55
- return self;
56
- }
57
-
58
- - (void)dealloc {
59
- [self stop];
60
-
61
-
62
- }
63
-
64
- #pragma mark -
65
- #pragma mark Extension methods
66
-
67
- - (void)kqueueFired {
68
- // Pull the native FD around which the CFFileDescriptor was wrapped
69
- int kq = CFFileDescriptorGetNativeDescriptor(_kqRef);
70
- if (kq < 0) return;
71
-
72
- // If we pull a single available event out of the queue, assume the directory was updated
73
- struct kevent event;
74
- struct timespec timeout = {0, 0};
75
- if (kevent(kq, NULL, 0, &event, 1, &timeout) == 1 && _update) {
76
- _update();
77
- }
78
-
79
- // (Re-)Enable a one-shot (the only kind) callback
80
- CFFileDescriptorEnableCallBacks(_kqRef, kCFFileDescriptorReadCallBack);
81
- }
82
-
83
-
84
- - (void)start {
85
- // One ping only
86
- if (_kqRef != NULL) return;
87
-
88
- // Fetch pathname of the directory to monitor
89
- NSString* docPath = self.path;
90
- if (!docPath) return;
91
-
92
- // Open an event-only file descriptor associated with the directory
93
- int dirFD = open([docPath fileSystemRepresentation], O_EVTONLY);
94
- if (dirFD < 0) return;
95
-
96
- // Create a new kernel event queue
97
- int kq = kqueue();
98
- if (kq < 0)
99
- {
100
- close(dirFD);
101
- return;
102
- }
103
-
104
- // Set up a kevent to monitor
105
- struct kevent eventToAdd; // Register an (ident, filter) pair with the kqueue
106
- eventToAdd.ident = dirFD; // The object to watch (the directory FD)
107
- eventToAdd.filter = EVFILT_VNODE; // Watch for certain events on the VNODE spec'd by ident
108
- eventToAdd.flags = EV_ADD | EV_CLEAR; // Add a resetting kevent
109
- eventToAdd.fflags = NOTE_WRITE; // The events to watch for on the VNODE spec'd by ident (writes)
110
- eventToAdd.data = 0; // No filter-specific data
111
- eventToAdd.udata = NULL; // No user data
112
-
113
- // Add a kevent to monitor
114
- if (kevent(kq, &eventToAdd, 1, NULL, 0, NULL)) {
115
- close(kq);
116
- close(dirFD);
117
- return;
118
- }
119
-
120
- // Wrap a CFFileDescriptor around a native FD
121
- CFFileDescriptorContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
122
- _kqRef = CFFileDescriptorCreate(NULL, // Use the default allocator
123
- kq, // Wrap the kqueue
124
- true, // Close the CFFileDescriptor if kq is invalidated
125
- KQCallback, // Fxn to call on activity
126
- &context); // Supply a context to set the callback's "info" argument
127
- if (_kqRef == NULL) {
128
- close(kq);
129
- close(dirFD);
130
- return;
131
- }
132
-
133
- // Spin out a pluggable run loop source from the CFFileDescriptorRef
134
- // Add it to the current run loop, then release it
135
- CFRunLoopSourceRef rls = CFFileDescriptorCreateRunLoopSource(NULL, _kqRef, 0);
136
- if (rls == NULL) {
137
- CFRelease(_kqRef); _kqRef = NULL;
138
- close(kq);
139
- close(dirFD);
140
- return;
141
- }
142
- CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
143
- CFRelease(rls);
144
-
145
- // Store the directory FD for later closing
146
- _dirFD = dirFD;
147
-
148
- // Enable a one-shot (the only kind) callback
149
- CFFileDescriptorEnableCallBacks(_kqRef, kCFFileDescriptorReadCallBack);
150
- }
151
-
152
- - (void)stop {
153
- if (_kqRef) {
154
- close(_dirFD);
155
- CFFileDescriptorInvalidate(_kqRef);
156
- CFRelease(_kqRef);
157
- _kqRef = NULL;
158
- }
159
- }
160
-
161
- @end
162
-
163
- #endif