From cb4e6d7f1925070aa2a278f6f58a9ea2bdca611d Mon Sep 17 00:00:00 2001 From: Charlie Qiu Date: Wed, 11 Jan 2017 10:43:37 +0800 Subject: [PATCH] Monitor pac file with GCD instead of FSEventStreamCreate. Old approach is not working on new version MacOS. --- ShadowsocksX-NG/ProxyConfHelper.m | 63 +++++++++++++------------------ 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/ShadowsocksX-NG/ProxyConfHelper.m b/ShadowsocksX-NG/ProxyConfHelper.m index 96c7ada..3665f11 100644 --- a/ShadowsocksX-NG/ProxyConfHelper.m +++ b/ShadowsocksX-NG/ProxyConfHelper.m @@ -211,45 +211,34 @@ FSEventStreamRef fsEventStream; } } -void onPACChange( - ConstFSEventStreamRef streamRef, - void *clientCallBackInfo, - size_t numEvents, - void *eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) -{ - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:@"ShadowsocksOn"]) { - if ([[defaults stringForKey:@"ShadowsocksRunningMode"] isEqualToString:@"auto"]) { - [ProxyConfHelper disableProxy]; - [ProxyConfHelper enablePACProxy]; - } - } -} - + (void)startMonitorPAC { NSString* PACFilePath = [self getPACFilePath]; - - if (fsEventStream) { - return; - } - CFStringRef mypath = (__bridge CFStringRef)(PACFilePath); - CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL); - void *callbackInfo = NULL; // could put stream-specific data here. - CFAbsoluteTime latency = 3.0; /* Latency in seconds */ - - /* Create the stream, passing in a callback */ - fsEventStream = FSEventStreamCreate(NULL, - &onPACChange, - callbackInfo, - pathsToWatch, - kFSEventStreamEventIdSinceNow, /* Or a previous event ID */ - latency, - kFSEventStreamCreateFlagNone /* Flags explained in reference */ - ); - FSEventStreamScheduleWithRunLoop(fsEventStream, [[NSRunLoop mainRunLoop] getCFRunLoop], (__bridge CFStringRef)NSDefaultRunLoopMode); - FSEventStreamStart(fsEventStream); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + int fileId = open([PACFilePath UTF8String], O_EVTONLY); + __block dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileId, + DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, + queue); + dispatch_source_set_event_handler(source, ^ + { + unsigned long flags = dispatch_source_get_data(source); + if(flags & DISPATCH_VNODE_DELETE) + { + dispatch_source_cancel(source); + } else { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + if ([defaults boolForKey:@"ShadowsocksOn"]) { + if ([[defaults stringForKey:@"ShadowsocksRunningMode"] isEqualToString:@"auto"]) { + [ProxyConfHelper disableProxy]; + [ProxyConfHelper enablePACProxy]; + } + } + } + }); + dispatch_source_set_cancel_handler(source, ^(void) + { + close(fileId); + }); + dispatch_resume(source); } @end