Bug 1274319: Allow elevated updater and Firefox on OSX to make 10 IPC connection attempts to the unelevated updater. r=mstange
authorStephen A Pohl <spohl.mozilla.bugs@gmail.com>
Tue, 24 May 2016 22:26:15 -0400
changeset 337887 ba0982c4e30cfbc79ef1f4e25c4a1afb0766cfec
parent 337886 ead4c5f8ae5767903780f9270134c82806d23169
child 337888 ce58234202e93b120b356a1a5436faa8b14ebcd9
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1274319
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1274319: Allow elevated updater and Firefox on OSX to make 10 IPC connection attempts to the unelevated updater. r=mstange
toolkit/mozapps/update/updater/launchchild_osx.mm
toolkit/xre/MacLaunchHelper.mm
--- a/toolkit/mozapps/update/updater/launchchild_osx.mm
+++ b/toolkit/mozapps/update/updater/launchchild_osx.mm
@@ -98,39 +98,65 @@ LaunchMacPostProcess(const char* aAppBun
     if ([exeAsync isEqualToString:@"false"]) {
       [task waitUntilExit];
     }
   }
   // ignore the return value of the task, there's nothing we can do with it
   [task release];
 }
 
-void CleanupElevatedMacUpdate(bool aFailureOccurred)
+id ConnectToUpdateServer()
 {
   MacAutoreleasePool pool;
 
   id updateServer = nil;
   @try {
-    updateServer = (id)[NSConnection
-      rootProxyForConnectionWithRegisteredName:
-        @"org.mozilla.updater.server"
-      host:nil
-      usingNameServer:[NSSocketPortNameServer sharedInstance]];
-    if (aFailureOccurred &&
-        updateServer &&
-        [updateServer respondsToSelector:@selector(abort)]) {
-      [updateServer performSelector:@selector(abort)];
-    }
-    else if (updateServer &&
-             [updateServer respondsToSelector:@selector(shutdown)]) {
-      [updateServer performSelector:@selector(shutdown)];
+    BOOL isConnected = NO;
+    int currTry = 0;
+    const int numRetries = 10; // Number of IPC connection retries before
+                               // giving up.
+    while (!isConnected && currTry < numRetries) {
+      updateServer = (id)[NSConnection
+        rootProxyForConnectionWithRegisteredName:
+          @"org.mozilla.updater.server"
+        host:nil
+        usingNameServer:[NSSocketPortNameServer sharedInstance]];
+      if (!updateServer ||
+          ![updateServer respondsToSelector:@selector(abort)] ||
+          ![updateServer respondsToSelector:@selector(getArguments)] ||
+          ![updateServer respondsToSelector:@selector(shutdown)]) {
+        NSLog(@"Server doesn't exist or doesn't provide correct selectors.");
+        sleep(1); // Wait 1 second.
+        currTry++;
+      } else {
+        isConnected = YES;
+      }
     }
   } @catch (NSException* e) {
     // Ignore exceptions.
+    return nil;
   }
+  return updateServer;
+}
+
+void CleanupElevatedMacUpdate(bool aFailureOccurred)
+{
+  MacAutoreleasePool pool;
+
+  id updateServer = ConnectToUpdateServer();
+  if (updateServer) {
+    @try {
+      if (aFailureOccurred) {
+        [updateServer performSelector:@selector(abort)];
+      } else {
+        [updateServer performSelector:@selector(shutdown)];
+      }
+    } @catch (NSException* e) { }
+  }
+
   NSFileManager* manager = [NSFileManager defaultManager];
   [manager removeItemAtPath:@"/Library/PrivilegedHelperTools/org.mozilla.updater"
                       error:nil];
   [manager removeItemAtPath:@"/Library/LaunchDaemons/org.mozilla.updater.plist"
                       error:nil];
   const char* launchctlArgs[] = {"/bin/launchctl",
                                  "remove",
                                  "org.mozilla.updater"};
@@ -139,31 +165,24 @@ void CleanupElevatedMacUpdate(bool aFail
   LaunchChild(3, launchctlArgs);
 }
 
 // Note: Caller is responsible for freeing argv.
 bool ObtainUpdaterArguments(int* argc, char*** argv)
 {
   MacAutoreleasePool pool;
 
-  id updateServer = nil;
+  id updateServer = ConnectToUpdateServer();
+  if (!updateServer) {
+    // Let's try our best and clean up.
+    CleanupElevatedMacUpdate(true);
+    return false; // Won't actually get here due to CleanupElevatedMacUpdate.
+  }
+
   @try {
-    updateServer = (id)[NSConnection
-      rootProxyForConnectionWithRegisteredName:
-        @"org.mozilla.updater.server"
-      host:nil
-      usingNameServer:[NSSocketPortNameServer sharedInstance]];
-    if (!updateServer ||
-        ![updateServer respondsToSelector:@selector(getArguments)] ||
-        ![updateServer respondsToSelector:@selector(shutdown)]) {
-      NSLog(@"Server doesn't exist or doesn't provide correct selectors.");
-      // Let's try our best and clean up.
-      CleanupElevatedMacUpdate(true);
-      return false; // Won't actually get here due to CleanupElevatedMacUpdate.
-    }
     NSArray* updaterArguments =
       [updateServer performSelector:@selector(getArguments)];
     *argc = [updaterArguments count];
     char** tempArgv = (char**)malloc(sizeof(char*) * (*argc));
     for (int i = 0; i < *argc; i++) {
       int argLen = [[updaterArguments objectAtIndex:i] length] + 1;
       tempArgv[i] = (char*)malloc(argLen);
       strncpy(tempArgv[i], [[updaterArguments objectAtIndex:i] UTF8String],
--- a/toolkit/xre/MacLaunchHelper.mm
+++ b/toolkit/xre/MacLaunchHelper.mm
@@ -142,32 +142,41 @@ BOOL InstallPrivilegedHelper()
   }
 
   return result;
 }
 
 void AbortElevatedUpdate()
 {
   mozilla::MacAutoreleasePool pool;
+
   id updateServer = nil;
   @try {
-    updateServer = (id)[NSConnection
-      rootProxyForConnectionWithRegisteredName:
-        @"org.mozilla.updater.server"
-      host:nil
-      usingNameServer:[NSSocketPortNameServer sharedInstance]];
-    if (updateServer &&
-        [updateServer respondsToSelector:@selector(abort)]) {
-      [updateServer performSelector:@selector(abort)];
-    } else {
-      NSLog(@"Unable to clean up updater.");
+    int currTry = 0;
+    const int numRetries = 10; // Number of IPC connection retries before
+                               // giving up.
+    while (currTry < numRetries) {
+      updateServer = (id)[NSConnection
+        rootProxyForConnectionWithRegisteredName:
+          @"org.mozilla.updater.server"
+        host:nil
+        usingNameServer:[NSSocketPortNameServer sharedInstance]];
+      if (updateServer &&
+          [updateServer respondsToSelector:@selector(abort)]) {
+        [updateServer performSelector:@selector(abort)];
+        return;
+      }
+      NSLog(@"Server doesn't exist or doesn't provide correct selectors.");
+      sleep(1); // Wait 1 second.
+      currTry++;
     }
   } @catch (NSException* e) {
     // Ignore exceptions.
   }
+  NSLog(@"Unable to clean up updater.");
 }
 
 bool LaunchElevatedUpdate(int argc, char** argv, uint32_t aRestartType,
                           pid_t* pid)
 {
   LaunchChildMac(argc, argv, aRestartType, pid);
   bool didSucceed = InstallPrivilegedHelper();
   if (!didSucceed) {