10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath.
1.1 --- a/MYDirectoryWatcher.m Mon Aug 10 08:29:32 2009 -0700
1.2 +++ b/MYDirectoryWatcher.m Wed Sep 02 08:41:25 2009 -0700
1.3 @@ -35,7 +35,8 @@
1.4 self = [super init];
1.5 if (self != nil) {
1.6 _path = path.copy;
1.7 - _standardizedPath = [[_path stringByStandardizingPath] copy];
1.8 + // stringByStandardizingPath is supposed to resolve symlinks, but in 10.6 this seems to have stopped happening...
1.9 + _standardizedPath = [[[path stringByResolvingSymlinksInPath] stringByStandardizingPath] copy];
1.10 _target = target;
1.11 _action = action;
1.12 _latency = 5.0;
1.13 @@ -198,7 +199,8 @@
1.14 - (NSString*) relativePath
1.15 {
1.16 NSString *base = watcher.standardizedPath;
1.17 - NSString *standardizedPath = [path stringByStandardizingPath];
1.18 + // stringByStandardizingPath is supposed to resolve symlinks, but in 10.6 this seems to have stopped happening...
1.19 + NSString *standardizedPath = [[path stringByResolvingSymlinksInPath] stringByStandardizingPath];
1.20 if( ! [standardizedPath hasPrefix: base] )
1.21 return nil;
1.22 unsigned length = base.length;
2.1 --- a/MYTask.m Mon Aug 10 08:29:32 2009 -0700
2.2 +++ b/MYTask.m Wed Sep 02 08:41:25 2009 -0700
2.3 @@ -9,7 +9,6 @@
2.4
2.5 //FIX: NOTICE: This code was written assuming garbage collection. It will currently leak like a sieve without it.
2.6
2.7 -
2.8 NSString* const MYTaskErrorDomain = @"MYTaskError";
2.9 NSString* const MYTaskExitCodeKey = @"MYTaskExitCode";
2.10 NSString* const MYTaskObjectKey = @"MYTask";
2.11 @@ -205,6 +204,8 @@
2.12 [self _close];
2.13 return [self makeError: @"Exception launching %@: %@",_task.launchPath,x];
2.14 }
2.15 + LogTo(MYTaskVerbose, @"Launched task, modes %@", _modes);
2.16 + Assert(_task.isRunning);
2.17 _taskRunning = YES;
2.18 self.isRunning = YES;
2.19
2.20 @@ -214,6 +215,7 @@
2.21
2.22 - (void) stop
2.23 {
2.24 + LogTo(MYTaskVerbose, @"Stopping task");
2.25 [_task interrupt];
2.26 [self _close];
2.27 _taskRunning = NO;
2.28 @@ -233,7 +235,7 @@
2.29 if( n.object == _outHandle ) {
2.30 if( data.length > 0 ) {
2.31 [_outHandle readInBackgroundAndNotifyForModes: _modes];
2.32 - LogTo(HgTaskVerbose, @"Got %u bytes of output",data.length);
2.33 + LogTo(MYTaskVerbose, @"Got %u bytes of output",data.length);
2.34 if( _outputData ) {
2.35 [self willChangeValueForKey: @"output"];
2.36 [self willChangeValueForKey: @"outputData"];
2.37 @@ -243,7 +245,7 @@
2.38 [self didChangeValueForKey: @"output"];
2.39 }
2.40 } else {
2.41 - LogTo(HgTaskVerbose, @"Closed output");
2.42 + LogTo(MYTaskVerbose, @"Closed output");
2.43 _outHandle = nil;
2.44 if( [self _shouldFinishUp] )
2.45 [self _finishUp];
2.46 @@ -257,12 +259,12 @@
2.47 NSData *data = [n.userInfo objectForKey: NSFileHandleNotificationDataItem];
2.48 if( data.length > 0 ) {
2.49 [_errHandle readInBackgroundAndNotifyForModes: _modes];
2.50 - LogTo(HgTaskVerbose, @"Got %u bytes of stderr",data.length);
2.51 + LogTo(MYTaskVerbose, @"Got %u bytes of stderr",data.length);
2.52 [self willChangeValueForKey: @"errorData"];
2.53 [_errorData appendData: data];
2.54 [self didChangeValueForKey: @"errorData"];
2.55 } else {
2.56 - LogTo(HgTaskVerbose, @"Closed stderr");
2.57 + LogTo(MYTaskVerbose, @"Closed stderr");
2.58 _errHandle = nil;
2.59 if( [self _shouldFinishUp] )
2.60 [self _finishUp];
2.61 @@ -273,7 +275,7 @@
2.62 - (void) _exited: (NSNotification*)n
2.63 {
2.64 _resultCode = _task.terminationStatus;
2.65 - LogTo(HgTaskVerbose, @"Exited with result=%i",_resultCode);
2.66 + LogTo(MYTaskVerbose, @"Exited with result=%i",_resultCode);
2.67 _taskRunning = NO;
2.68 if( [self _shouldFinishUp] )
2.69 [self _finishUp];
2.70 @@ -287,7 +289,7 @@
2.71 [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(_finishUp) object: nil];
2.72 [self _close];
2.73
2.74 - LogTo(HgTaskVerbose, @"Finished!");
2.75 + LogTo(MYTaskVerbose, @"Finished!");
2.76
2.77 if( _resultCode != 0 ) {
2.78 // Handle errors:
2.79 @@ -326,8 +328,22 @@
2.80 {
2.81 // wait for task to exit:
2.82 while( _task.isRunning || self.isRunning )
2.83 - [[NSRunLoop currentRunLoop] runMode: MYTaskSynchronousRunLoopMode
2.84 - beforeDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]];
2.85 + if (![[NSRunLoop currentRunLoop] runMode: runLoopMode
2.86 + beforeDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]]) {
2.87 + // This happens if both stderr and stdout are closed (leaving no NSFileHandles running
2.88 + // in this runloop mode) but the task hasn't yet notified me that it exited.
2.89 + // For some reason, in 10.6 the notification sometimes just doesn't appear, so poll
2.90 + // for it:
2.91 + if (_task.isRunning) {
2.92 + Warn(@"MYTask _waitTillFinishedInMode: no runloop sources left for %@ mode; waiting...", runLoopMode);
2.93 + sleep(1);
2.94 + } else {
2.95 + Warn(@"MYTask _waitTillFinishedInMode: Task exited without notifying!");
2.96 + [self _exited: nil];
2.97 + }
2.98 + } else
2.99 + LogTo(MYTaskVerbose, @"..._waitTillFinishedInMode still waiting...");
2.100 +
2.101 return (_resultCode==0);
2.102 }
2.103
3.1 --- a/Test.h Mon Aug 10 08:29:32 2009 -0700
3.2 +++ b/Test.h Wed Sep 02 08:41:25 2009 -0700
3.3 @@ -93,7 +93,7 @@
3.4
3.5 struct TestCaseLink {void (*testptr)(); const char *name; BOOL passed; struct TestCaseLink *next;};
3.6 extern struct TestCaseLink *gAllTestCases;
3.7 -#endif DEBUG
3.8 +#endif // DEBUG
3.9 void _AssertFailed( id rcvr, const void *selOrFn, const char *sourceFile, int sourceLine,
3.10 const char *condString, NSString *message, ... ) __attribute__((noreturn));
3.11 void _AssertAbstractMethodFailed( id rcvr, SEL cmd) __attribute__((noreturn));
4.1 --- a/Test.m Mon Aug 10 08:29:32 2009 -0700
4.2 +++ b/Test.m Wed Sep 02 08:41:25 2009 -0700
4.3 @@ -120,7 +120,7 @@
4.4 }
4.5
4.6
4.7 -#endif DEBUG
4.8 +#endif // DEBUG
4.9
4.10
4.11 #pragma mark -