10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath. default tip
authorJens Alfke <jens@mooseyard.com>
Wed Sep 02 08:41:25 2009 -0700 (2009-09-02)
changeset 355cab3034d3a1
parent 34 50c4f26bcc1b
10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath.
MYDirectoryWatcher.m
MYTask.m
Test.h
Test.m
     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 -