rb-fsevent 0.9.2 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/Gemfile +3 -0
  4. data/Guardfile +8 -0
  5. data/{LICENSE → LICENSE.txt} +3 -1
  6. data/README.md +260 -0
  7. data/Rakefile +33 -0
  8. data/bin/fsevent_watch +0 -0
  9. data/ext/{fsevent_watch/LICENSE → LICENSE} +1 -1
  10. data/ext/fsevent_watch/FSEventsFix.c +626 -0
  11. data/ext/fsevent_watch/FSEventsFix.h +105 -0
  12. data/ext/fsevent_watch/{fsevent_watch/TSICTString.c → TSICTString.c} +34 -55
  13. data/ext/fsevent_watch/{fsevent_watch/TSICTString.h → TSICTString.h} +0 -0
  14. data/ext/fsevent_watch/{fsevent_watch/cli.c → cli.c} +48 -7
  15. data/ext/fsevent_watch/{fsevent_watch/cli.h → cli.h} +3 -3
  16. data/ext/fsevent_watch/{fsevent_watch/common.h → common.h} +1 -13
  17. data/ext/fsevent_watch/compat.c +41 -0
  18. data/ext/fsevent_watch/compat.h +100 -0
  19. data/ext/fsevent_watch/defines.h +42 -0
  20. data/ext/fsevent_watch/{fsevent_watch/main.c → main.c} +101 -62
  21. data/ext/fsevent_watch/signal_handlers.c +66 -0
  22. data/ext/fsevent_watch/signal_handlers.h +16 -0
  23. data/ext/rakefile.rb +225 -41
  24. data/lib/otnetstring.rb +85 -0
  25. data/lib/rb-fsevent/fsevent.rb +53 -7
  26. data/lib/rb-fsevent/version.rb +3 -1
  27. data/lib/rb-fsevent.rb +2 -1
  28. data/rb-fsevent.gemspec +26 -0
  29. metadata +53 -56
  30. data/README.rdoc +0 -255
  31. data/ext/fsevent_watch/Info.plist +0 -38
  32. data/ext/fsevent_watch/fsevent_watch/compat.c +0 -20
  33. data/ext/fsevent_watch/fsevent_watch/compat.h +0 -40
  34. data/ext/fsevent_watch/fsevent_watch.xcodeproj/project.pbxproj +0 -254
  35. data/ext/fsevent_watch/xcconfig/Common.xcconfig +0 -82
  36. data/ext/fsevent_watch/xcconfig/Debug.xcconfig +0 -19
  37. data/ext/fsevent_watch/xcconfig/Release.xcconfig +0 -23
  38. data/ext/fsevent_watch/xcconfig/fsevent_watch.xcconfig +0 -17
  39. data/ext/rb-fsevent.xcconfig +0 -33
@@ -0,0 +1,105 @@
1
+ /*
2
+ * FSEventsFix
3
+ *
4
+ * Works around a long-standing bug in realpath() that prevents FSEvents API from
5
+ * monitoring certain folders on a wide range of OS X releases (10.6-10.10 at least).
6
+ *
7
+ * The underlying issue is that for some folders, realpath() call starts returning
8
+ * a path with incorrect casing (e.g. "/users/smt" instead of "/Users/smt").
9
+ * FSEvents is case-sensitive and calls realpath() on the paths you pass in, so
10
+ * an incorrect value returned by realpath() prevents FSEvents from seeing any
11
+ * change events.
12
+ *
13
+ * See the discussion at https://github.com/thibaudgg/rb-fsevent/issues/10 about
14
+ * the history of this bug and how this library came to exist.
15
+ *
16
+ * This library uses Facebook's fishhook to replace a custom implementation of
17
+ * realpath in place of the system realpath; FSEvents will then invoke our custom
18
+ * implementation (which does not screw up the names) and will thus work correctly.
19
+ *
20
+ * Our implementation of realpath is based on the open-source implementation from
21
+ * OS X 10.10, with a single change applied (enclosed in "BEGIN WORKAROUND FOR
22
+ * OS X BUG" ... "END WORKAROUND FOR OS X BUG").
23
+ *
24
+ * Include FSEventsFix.{h,c} into your project and call FSEventsFixInstall().
25
+ *
26
+ * It is recommended that you install FSEventsFix on demand, using FSEventsFixIsBroken
27
+ * to check if the folder you're about to pass to FSEventStreamCreate needs the fix.
28
+ * Note that the fix must be applied before calling FSEventStreamCreate.
29
+ *
30
+ * FSEventsFixIsBroken requires a path that uses the correct case for all folder names,
31
+ * i.e. a path provided by the system APIs or constructed from folder names provided
32
+ * by the directory enumeration APIs.
33
+ *
34
+ * See .c file for license & copyrights, but basically this is available under a mix
35
+ * of MIT and BSD licenses.
36
+ */
37
+
38
+ #ifndef __FSEventsFix__
39
+ #define __FSEventsFix__
40
+
41
+ #include <CoreFoundation/CoreFoundation.h>
42
+
43
+ /// A library version string (e.g. 1.2.3) for displaying and logging purposes
44
+ extern const char *const FSEventsFixVersionString;
45
+
46
+ /// See FSEventsFixDebugOptionSimulateBroken
47
+ #define FSEventsFixSimulatedBrokenFolderMarker "__!FSEventsBroken!__"
48
+
49
+ typedef CF_OPTIONS(unsigned, FSEventsFixDebugOptions) {
50
+ /// Always return an uppercase string from realpath
51
+ FSEventsFixDebugOptionUppercaseReturn = 0x01,
52
+
53
+ /// Log all calls to realpath using the logger configured via FSEventsFixConfigure
54
+ FSEventsFixDebugOptionLogCalls = 0x02,
55
+
56
+ /// In addition to the logging block (if any), log everything to stderr
57
+ FSEventsFixDebugOptionLogToStderr = 0x08,
58
+
59
+ /// Report paths containing FSEventsFixSimulatedBrokenFolderMarker as broken
60
+ FSEventsFixDebugOptionSimulateBroken = 0x10,
61
+
62
+ /// Repair paths containing FSEventsFixSimulatedBrokenFolderMarker by renaming them
63
+ FSEventsFixDebugOptionSimulateRepair = 0x20,
64
+ };
65
+
66
+ typedef CF_ENUM(int, FSEventsFixMessageType) {
67
+ /// Call logging requested via FSEventsFixDebugOptionLogCalls
68
+ FSEventsFixMessageTypeCall,
69
+
70
+ /// Results of actions like repair, and other pretty verbose, but notable, stuff.
71
+ FSEventsFixMessageTypeResult,
72
+
73
+ /// Enabled/disabled status change
74
+ FSEventsFixMessageTypeStatusChange,
75
+
76
+ /// Expected failure (treat as a warning)
77
+ FSEventsFixMessageTypeExpectedFailure,
78
+
79
+ /// Severe failure that most likely means that the library won't work
80
+ FSEventsFixMessageTypeFatalError
81
+ };
82
+
83
+ typedef CF_ENUM(int, FSEventsFixRepairStatus) {
84
+ FSEventsFixRepairStatusNotBroken,
85
+ FSEventsFixRepairStatusRepaired,
86
+ FSEventsFixRepairStatusFailed,
87
+ };
88
+
89
+ /// Note that the logging block can be called on any dispatch queue.
90
+ void FSEventsFixConfigure(FSEventsFixDebugOptions debugOptions, void(^loggingBlock)(FSEventsFixMessageType type, const char *message));
91
+
92
+ void FSEventsFixEnable();
93
+ void FSEventsFixDisable();
94
+
95
+ bool FSEventsFixIsOperational();
96
+
97
+ bool FSEventsFixIsBroken(const char *path);
98
+
99
+ /// If the path is broken, returns a string identifying the root broken folder,
100
+ /// otherwise, returns NULL. You need to free() the returned string.
101
+ char *FSEventsFixCopyRootBrokenFolderPath(const char *path);
102
+
103
+ FSEventsFixRepairStatus FSEventsFixRepairIfNeeded(const char *path);
104
+
105
+ #endif
@@ -65,13 +65,13 @@ static inline TStringIRep* TSICTStringCreateWithDataOfTypeAndFormat(CFDataRef da
65
65
  if (format == kTSITStringFormatDefault) {
66
66
  format = TSICTStringGetDefaultFormat();
67
67
  }
68
-
68
+
69
69
  TStringIRep* rep = calloc(1, sizeof(TStringIRep));
70
70
  rep->data = CFDataCreateCopy(kCFAllocatorDefault, data);
71
71
  rep->type = type;
72
72
  rep->format = format;
73
73
  rep->length = calloc(10, sizeof(char));
74
-
74
+
75
75
  CFIndex len = CFDataGetLength(rep->data);
76
76
  if (snprintf(rep->length, 10, "%lu", len)) {
77
77
  return rep;
@@ -86,10 +86,10 @@ static inline CFDataRef TSICTStringCreateDataFromIntermediateRepresentation(TStr
86
86
  CFIndex len = CFDataGetLength(rep->data);
87
87
  CFMutableDataRef buffer = CFDataCreateMutableCopy(kCFAllocatorDefault, (len + 12), rep->data);
88
88
  UInt8* bufferBytes = CFDataGetMutableBytePtr(buffer);
89
-
89
+
90
90
  size_t prefixLength = strlen(rep->length) + 1;
91
91
  CFDataReplaceBytes(buffer, BeginningRange, (const UInt8*)rep->length, (CFIndex)prefixLength);
92
-
92
+
93
93
  if (rep->format == kTSITStringFormatTNetstring) {
94
94
  const UInt8 ftag = (UInt8)TNetstringTypes[rep->type];
95
95
  CFDataAppendBytes(buffer, &ftag, 1);
@@ -98,10 +98,10 @@ static inline CFDataRef TSICTStringCreateDataFromIntermediateRepresentation(TStr
98
98
  const UInt8 ftag = (UInt8)OTNetstringTypes[rep->type];
99
99
  bufferBytes[(prefixLength - 1)] = ftag;
100
100
  }
101
-
101
+
102
102
  CFDataRef dataRep = CFDataCreateCopy(kCFAllocatorDefault, buffer);
103
103
  CFRelease(buffer);
104
-
104
+
105
105
  return dataRep;
106
106
  }
107
107
 
@@ -113,41 +113,20 @@ static inline CFStringRef TSICTStringCreateStringFromIntermediateRepresentation(
113
113
  return string;
114
114
  }
115
115
 
116
- static inline CFDataRef TSICTStringCreateDataWithDataOfTypeAndFormat(CFDataRef data, TSITStringTag type, TSITStringFormat format)
117
- {
118
- CFRetain(data);
119
-
120
- if (format == kTSITStringFormatDefault) {
121
- format = TSICTStringGetDefaultFormat();
122
- }
123
-
124
- TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, type, format);
125
- if (rep == NULL) {
126
- return NULL;
127
- }
128
-
129
- CFDataRef result = TSICTStringCreateDataFromIntermediateRepresentation(rep);
130
-
131
- TSICTStringDestroy(rep);
132
- CFRelease(data);
133
-
134
- return result;
135
- }
136
-
137
116
  static inline void TSICTStringAppendObjectToMutableDataWithFormat(CFTypeRef object, CFMutableDataRef buffer, TSITStringFormat format)
138
117
  {
139
118
  if (object == NULL) {
140
119
  object = kCFNull;
141
120
  }
142
-
121
+
143
122
  CFRetain(object);
144
-
123
+
145
124
  TStringIRep* objRep = TSICTStringCreateWithObjectAndFormat(object, format);
146
125
  CFDataRef objData = TSICTStringCreateDataFromIntermediateRepresentation(objRep);
147
126
  CFDataAppendBytes(buffer, (CFDataGetBytePtr(objData)), CFDataGetLength(objData));
148
127
  CFRelease(objData);
149
128
  TSICTStringDestroy(objRep);
150
-
129
+
151
130
  CFRelease(object);
152
131
  }
153
132
 
@@ -156,7 +135,7 @@ static void ArrayBufferAppendCallback(const void* item, void* context)
156
135
  TStringCollectionCallbackContext* cx = (TStringCollectionCallbackContext*)context;
157
136
  CFMutableDataRef buffer = cx->buffer;
158
137
  TSITStringFormat format = cx->format;
159
-
138
+
160
139
  TSICTStringAppendObjectToMutableDataWithFormat(item, buffer, format);
161
140
  }
162
141
 
@@ -165,7 +144,7 @@ static void DictionaryBufferAppendCallback(const void* key, const void* value, v
165
144
  TStringCollectionCallbackContext* cx = (TStringCollectionCallbackContext*)context;
166
145
  CFMutableDataRef buffer = cx->buffer;
167
146
  TSITStringFormat format = cx->format;
168
-
147
+
169
148
  TSICTStringAppendObjectToMutableDataWithFormat(key, buffer, format);
170
149
  TSICTStringAppendObjectToMutableDataWithFormat(value, buffer, format);
171
150
  }
@@ -181,15 +160,15 @@ CFDataRef TSICTStringCreateRenderedDataFromObjectWithFormat(CFTypeRef object, TS
181
160
  if (object == NULL) {
182
161
  object = kCFNull;
183
162
  }
184
-
163
+
185
164
  CFRetain(object);
186
-
165
+
187
166
  TStringIRep* rep = TSICTStringCreateWithObjectAndFormat(object, format);
188
167
  CFDataRef data = TSICTStringCreateDataFromIntermediateRepresentation(rep);
189
-
168
+
190
169
  TSICTStringDestroy(rep);
191
170
  CFRelease(object);
192
-
171
+
193
172
  return data;
194
173
  }
195
174
 
@@ -203,15 +182,15 @@ CFStringRef TSICTStringCreateRenderedStringFromObjectWithFormat(CFTypeRef object
203
182
  if (object == NULL) {
204
183
  object = kCFNull;
205
184
  }
206
-
185
+
207
186
  CFRetain(object);
208
-
187
+
209
188
  TStringIRep* rep = TSICTStringCreateWithObjectAndFormat(object, format);
210
189
  CFStringRef string = TSICTStringCreateStringFromIntermediateRepresentation(rep);
211
-
190
+
212
191
  TSICTStringDestroy(rep);
213
192
  CFRelease(object);
214
-
193
+
215
194
  return string;
216
195
  }
217
196
 
@@ -222,10 +201,10 @@ TStringIRep* TSICTStringCreateWithObjectAndFormat(CFTypeRef object, TSITStringFo
222
201
  return TSICTStringCreateNullWithFormat(format);
223
202
  }
224
203
  CFRetain(object);
225
-
204
+
226
205
  CFTypeID cfType = CFGetTypeID(object);
227
206
  TStringIRep* rep = NULL;
228
-
207
+
229
208
  if (cfType == kCFDataTypeID) {
230
209
  rep = TSICTStringCreateWithDataOfTypeAndFormat(object, kTSITStringTagString, format);
231
210
  } else if (cfType == kCFStringTypeID) {
@@ -247,7 +226,7 @@ TStringIRep* TSICTStringCreateWithObjectAndFormat(CFTypeRef object, TSITStringFo
247
226
  } else {
248
227
  rep = TSICTStringCreateInvalidWithFormat(format);
249
228
  }
250
-
229
+
251
230
  CFRelease(object);
252
231
  return rep;
253
232
  }
@@ -268,7 +247,7 @@ TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITString
268
247
  TSITStringTag tag = kTSITStringTagNumber;
269
248
  CFDataRef data;
270
249
  CFNumberType numType = CFNumberGetType(number);
271
-
250
+
272
251
  switch(numType) {
273
252
  case kCFNumberCharType:
274
253
  {
@@ -291,7 +270,7 @@ TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITString
291
270
  break;
292
271
  }
293
272
  }
294
-
273
+
295
274
  if (tag == kTSITStringTagBool) {
296
275
  bool value;
297
276
  CFNumberGetValue(number, kCFNumberIntType, &value);
@@ -304,17 +283,17 @@ TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITString
304
283
  char buf[32];
305
284
  char *p, *e;
306
285
  double value;
307
-
286
+
308
287
  CFNumberGetValue(number, numType, &value);
309
288
  sprintf(buf, "%#.15g", value);
310
-
289
+
311
290
  e = buf + strlen(buf);
312
291
  p = e;
313
292
  while (p[-1]=='0' && ('0' <= p[-2] && p[-2] <= '9')) {
314
293
  p--;
315
294
  }
316
295
  memmove(p, e, strlen(e)+1);
317
-
296
+
318
297
  data = CFDataCreate(kCFAllocatorDefault, (UInt8*)buf, (CFIndex)strlen(buf));
319
298
  } else {
320
299
  char buf[32];
@@ -323,7 +302,7 @@ TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITString
323
302
  sprintf(buf, "%lli", value);
324
303
  data = CFDataCreate(kCFAllocatorDefault, (UInt8*)buf, (CFIndex)strlen(buf));
325
304
  }
326
-
305
+
327
306
  TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, tag, format);
328
307
  CFRelease(data);
329
308
  CFRelease(number);
@@ -365,13 +344,13 @@ TStringIRep* TSICTStringCreateInvalidWithFormat(TSITStringFormat format)
365
344
  TStringIRep* TSICTStringCreateWithArrayAndFormat(CFArrayRef array, TSITStringFormat format)
366
345
  {
367
346
  CFRetain(array);
368
-
347
+
369
348
  CFMutableDataRef buffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
370
-
349
+
371
350
  CFRange all = CFRangeMake(0, CFArrayGetCount(array));
372
351
  TStringCollectionCallbackContext cx = {buffer, format};
373
352
  CFArrayApplyFunction(array, all, ArrayBufferAppendCallback, &cx);
374
-
353
+
375
354
  TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(buffer, kTSITStringTagList, format);
376
355
  CFRelease(buffer);
377
356
  CFRelease(array);
@@ -381,12 +360,12 @@ TStringIRep* TSICTStringCreateWithArrayAndFormat(CFArrayRef array, TSITStringFor
381
360
  TStringIRep* TSICTStringCreateWithDictionaryAndFormat(CFDictionaryRef dictionary, TSITStringFormat format)
382
361
  {
383
362
  CFRetain(dictionary);
384
-
363
+
385
364
  CFMutableDataRef buffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
386
-
365
+
387
366
  TStringCollectionCallbackContext cx = {buffer, format};
388
367
  CFDictionaryApplyFunction(dictionary, DictionaryBufferAppendCallback, &cx);
389
-
368
+
390
369
  TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(buffer, kTSITStringTagDict, format);
391
370
  CFRelease(buffer);
392
371
  CFRelease(dictionary);
@@ -6,6 +6,7 @@ const char* cli_info_usage = "Usage: fsevent_watch [OPTIONS]... [PATHS]...";
6
6
  const char* cli_info_help[] = {
7
7
  " -h, --help you're looking at it",
8
8
  " -V, --version print version number and exit",
9
+ " -p, --show-plist display the embedded Info.plist values",
9
10
  " -s, --since-when=EventID fire historical events since ID",
10
11
  " -l, --latency=seconds latency period (default='0.5')",
11
12
  " -n, --no-defer enable no-defer latency modifier",
@@ -25,7 +26,8 @@ static void default_args (struct cli_info* args_info)
25
26
  args_info->watch_root_flag = false;
26
27
  args_info->ignore_self_flag = false;
27
28
  args_info->file_events_flag = false;
28
- args_info->format_arg = kFSEventWatchOutputFormatClassic;
29
+ args_info->mark_self_flag = false;
30
+ args_info->format_arg = kFSEventWatchOutputFormatOTNetstring;
29
31
  }
30
32
 
31
33
  static void cli_parser_release (struct cli_info* args_info)
@@ -56,12 +58,46 @@ void cli_parser_free (struct cli_info* args_info)
56
58
  cli_parser_release(args_info);
57
59
  }
58
60
 
61
+ static void cli_print_info_dict (const void *key,
62
+ const void *value,
63
+ void *context)
64
+ {
65
+ CFStringRef entry = CFStringCreateWithFormat(NULL, NULL,
66
+ CFSTR("%@:\n %@"), key, value);
67
+ if (entry) {
68
+ CFShow(entry);
69
+ CFRelease(entry);
70
+ }
71
+ }
72
+
73
+ void cli_show_plist (void)
74
+ {
75
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
76
+ CFRetain(mainBundle);
77
+ CFDictionaryRef mainBundleDict = CFBundleGetInfoDictionary(mainBundle);
78
+ if (mainBundleDict) {
79
+ CFRetain(mainBundleDict);
80
+ printf("Embedded Info.plist metadata:\n\n");
81
+ CFDictionaryApplyFunction(mainBundleDict, cli_print_info_dict, NULL);
82
+ CFRelease(mainBundleDict);
83
+ }
84
+ CFRelease(mainBundle);
85
+ printf("\n");
86
+ }
87
+
59
88
  void cli_print_version (void)
60
89
  {
61
- printf("%s %s\n", CLI_NAME, CLI_VERSION);
90
+ printf("%s %s\n\n", CLI_NAME, CLI_VERSION);
62
91
  #ifdef COMPILED_AT
63
- printf("Compiled %s\n", COMPILED_AT);
92
+ printf("Compiled at: %s\n", COMPILED_AT);
64
93
  #endif
94
+ #ifdef COMPILER
95
+ printf("Compiled with: %s\n", COMPILER);
96
+ #endif
97
+ #ifdef TARGET_CPU
98
+ printf("Compiled for: %s\n", TARGET_CPU);
99
+ #endif
100
+ printf("\n");
65
101
  }
66
102
 
67
103
  void cli_print_help (void)
@@ -83,17 +119,19 @@ int cli_parser (int argc, const char** argv, struct cli_info* args_info)
83
119
  static struct option longopts[] = {
84
120
  { "help", no_argument, NULL, 'h' },
85
121
  { "version", no_argument, NULL, 'V' },
122
+ { "show-plist", no_argument, NULL, 'p' },
86
123
  { "since-when", required_argument, NULL, 's' },
87
124
  { "latency", required_argument, NULL, 'l' },
88
125
  { "no-defer", no_argument, NULL, 'n' },
89
126
  { "watch-root", no_argument, NULL, 'r' },
90
127
  { "ignore-self", no_argument, NULL, 'i' },
91
128
  { "file-events", no_argument, NULL, 'F' },
129
+ { "mark-self", no_argument, NULL, 'm' },
92
130
  { "format", required_argument, NULL, 'f' },
93
131
  { 0, 0, 0, 0 }
94
132
  };
95
133
 
96
- const char* shortopts = "hVs:l:nriFf:";
134
+ const char* shortopts = "hVps:l:nriFf:";
97
135
 
98
136
  int c = -1;
99
137
 
@@ -117,6 +155,9 @@ int cli_parser (int argc, const char** argv, struct cli_info* args_info)
117
155
  case 'F': // file-events
118
156
  args_info->file_events_flag = true;
119
157
  break;
158
+ case 'm': // mark-self
159
+ args_info->mark_self_flag = true;
160
+ break;
120
161
  case 'f': // format
121
162
  if (strcmp(optarg, "classic") == 0) {
122
163
  args_info->format_arg = kFSEventWatchOutputFormatClassic;
@@ -134,13 +175,14 @@ int cli_parser (int argc, const char** argv, struct cli_info* args_info)
134
175
  case 'V': // version
135
176
  cli_print_version();
136
177
  exit(EXIT_SUCCESS);
137
- break;
178
+ case 'p': // show-plist
179
+ cli_show_plist();
180
+ exit(EXIT_SUCCESS);
138
181
  case 'h': // help
139
182
  case '?': // invalid option
140
183
  case ':': // missing argument
141
184
  cli_print_help();
142
185
  exit((c == 'h') ? EXIT_SUCCESS : EXIT_FAILURE);
143
- break;
144
186
  }
145
187
  }
146
188
 
@@ -157,4 +199,3 @@ int cli_parser (int argc, const char** argv, struct cli_info* args_info)
157
199
 
158
200
  return EXIT_SUCCESS;
159
201
  }
160
-
@@ -1,6 +1,8 @@
1
1
  #ifndef CLI_H
2
2
  #define CLI_H
3
3
 
4
+ #include "common.h"
5
+
4
6
  #ifndef CLI_NAME
5
7
  #define CLI_NAME "fsevent_watch"
6
8
  #endif /* CLI_NAME */
@@ -10,12 +12,9 @@
10
12
  #endif /* PROJECT_VERSION */
11
13
 
12
14
  #ifndef CLI_VERSION
13
- #define _str(s) #s
14
- #define _xstr(s) _str(s)
15
15
  #define CLI_VERSION _xstr(PROJECT_VERSION)
16
16
  #endif /* CLI_VERSION */
17
17
 
18
- #include "common.h"
19
18
 
20
19
  struct cli_info {
21
20
  UInt64 since_when_arg;
@@ -24,6 +23,7 @@ struct cli_info {
24
23
  bool watch_root_flag;
25
24
  bool ignore_self_flag;
26
25
  bool file_events_flag;
26
+ bool mark_self_flag;
27
27
  enum FSEventWatchOutputFormat format_arg;
28
28
 
29
29
  char** inputs;
@@ -9,21 +9,9 @@
9
9
  #include <CoreServices/CoreServices.h>
10
10
  #include <unistd.h>
11
11
  #include "compat.h"
12
+ #include "defines.h"
12
13
  #include "TSICTString.h"
13
14
 
14
- #define COMPILED_AT __DATE__ " " __TIME__
15
-
16
- #define FLAG_CHECK(flags, flag) ((flags) & (flag))
17
-
18
- #define FPRINTF_FLAG_CHECK(flags, flag, msg, fd) \
19
- do { \
20
- if (FLAG_CHECK(flags, flag)) { \
21
- fprintf(fd, "%s", msg "\n"); } } \
22
- while (0)
23
-
24
- #define FLAG_CHECK_STDERR(flags, flag, msg) \
25
- FPRINTF_FLAG_CHECK(flags, flag, msg, stderr)
26
-
27
15
  enum FSEventWatchOutputFormat {
28
16
  kFSEventWatchOutputFormatClassic,
29
17
  kFSEventWatchOutputFormatNIW,
@@ -0,0 +1,41 @@
1
+ #include "compat.h"
2
+
3
+
4
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
5
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
6
+ FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf = 0x00000008;
7
+ #endif
8
+
9
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
10
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
11
+ FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents = 0x00000010;
12
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated = 0x00000100;
13
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemRemoved = 0x00000200;
14
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
15
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemRenamed = 0x00000800;
16
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemModified = 0x00001000;
17
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
18
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
19
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemXattrMod = 0x00008000;
20
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsFile = 0x00010000;
21
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsDir = 0x00020000;
22
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
23
+ #endif
24
+
25
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
26
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
27
+ FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf = 0x00000020;
28
+ FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent = 0x00080000;
29
+ #endif
30
+
31
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
32
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
33
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink = 0x00100000;
34
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsLastHardlink = 0x00200000;
35
+ #endif
36
+
37
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
38
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
39
+ FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData = 0x00000040;
40
+ FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned = 0x00400000;
41
+ #endif
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @headerfile compat.h
3
+ * FSEventStream flag compatibility shim
4
+ *
5
+ * In order to compile a binary against an older SDK yet still support the
6
+ * features present in later OS releases, we need to define any missing enum
7
+ * constants not present in the older SDK. This allows us to safely defer
8
+ * feature detection to runtime (and avoid recompilation).
9
+ */
10
+
11
+
12
+ #ifndef listen_fsevents_compat_h
13
+ #define listen_fsevents_compat_h
14
+
15
+ #ifndef __CORESERVICES__
16
+ #include <CoreServices/CoreServices.h>
17
+ #endif // __CORESERVICES__
18
+
19
+ #ifndef __AVAILABILITY__
20
+ #include <Availability.h>
21
+ #endif // __AVAILABILITY__
22
+
23
+ #ifndef __MAC_10_6
24
+ #define __MAC_10_6 1060
25
+ #endif
26
+ #ifndef __MAC_10_7
27
+ #define __MAC_10_7 1070
28
+ #endif
29
+ #ifndef __MAC_10_9
30
+ #define __MAC_10_9 1090
31
+ #endif
32
+ #ifndef __MAC_10_10
33
+ #define __MAC_10_10 101000
34
+ #endif
35
+ #ifndef __MAC_10_13
36
+ #define __MAC_10_13 101300
37
+ #endif
38
+ #ifndef __IPHONE_6_0
39
+ #define __IPHONE_6_0 60000
40
+ #endif
41
+ #ifndef __IPHONE_7_0
42
+ #define __IPHONE_7_0 70000
43
+ #endif
44
+ #ifndef __IPHONE_9_0
45
+ #define __IPHONE_9_0 90000
46
+ #endif
47
+ #ifndef __IPHONE_11_0
48
+ #define __IPHONE_11_0 110000
49
+ #endif
50
+
51
+ #ifdef __cplusplus
52
+ extern "C" {
53
+ #endif
54
+
55
+
56
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
57
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
58
+ extern FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf;
59
+ #endif
60
+
61
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
62
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
63
+ extern FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents;
64
+ extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated,
65
+ kFSEventStreamEventFlagItemRemoved,
66
+ kFSEventStreamEventFlagItemInodeMetaMod,
67
+ kFSEventStreamEventFlagItemRenamed,
68
+ kFSEventStreamEventFlagItemModified,
69
+ kFSEventStreamEventFlagItemFinderInfoMod,
70
+ kFSEventStreamEventFlagItemChangeOwner,
71
+ kFSEventStreamEventFlagItemXattrMod,
72
+ kFSEventStreamEventFlagItemIsFile,
73
+ kFSEventStreamEventFlagItemIsDir,
74
+ kFSEventStreamEventFlagItemIsSymlink;
75
+ #endif
76
+
77
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
78
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
79
+ extern FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf;
80
+ extern FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent;
81
+ #endif
82
+
83
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
84
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
85
+ extern FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink,
86
+ kFSEventStreamEventFlagItemIsLastHardlink;
87
+ #endif
88
+
89
+ #if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
90
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
91
+ extern FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData;
92
+ extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned;
93
+ #endif
94
+
95
+
96
+ #ifdef __cplusplus
97
+ }
98
+ #endif
99
+
100
+ #endif // listen_fsevents_compat_h