rb-fsevent 0.9.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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