Launch Firefox from updater using NSTask instead of system to allow the

updater process to exit.  Otherwise, the user will see the updater icon
in the dock once Firefox launches.  This patch also moves the rest of
the systems away from 'system' to invoke Firefox.
This commit is contained in:
darin%meer.net 2005-06-23 04:03:40 +00:00
parent e646de80cd
commit 99b3b6aaf5
3 changed files with 97 additions and 17 deletions

View File

@ -85,7 +85,7 @@ endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
HAVE_PROGRESSUI = 1
CPPSRCS += readstrings.cpp
CMMSRCS += progressui_osx.mm
CMMSRCS += progressui_osx.mm launchchild_osx.mm
OS_LIBS += -framework Cocoa
endif

View File

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <Cocoa/Cocoa.h>
void LaunchChild(int argc, char **argv)
{
int i;
NSTask *child = [[NSTask alloc] init];
NSMutableArray *args = [[NSMutableArray alloc] init];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (i = 1; i < argc; ++i)
[args addObject: [NSString stringWithCString: argv[i]]];
[child setLaunchPath: [NSString stringWithCString: argv[0]]];
[child setArguments: args];
[child launch];
[pool release];
}

View File

@ -78,6 +78,11 @@
# include <unistd.h>
#endif
#if defined(XP_MACOSX)
// This function is defined in launchchild_osx.mm
void LaunchChild(int argc, char **argv);
#endif
#ifndef _O_BINARY
# define _O_BINARY 0
#endif
@ -102,6 +107,12 @@
# endif
#endif
// We want to use execv to invoke the callback executable on platforms where
// we were launched using execv. See nsUpdateDriver.cpp.
#if defined(XP_UNIX) && !defined(XP_MACOSX)
#define USE_EXECV
#endif
//-----------------------------------------------------------------------------
// This variable lives in libbz2. It's declared in bzlib_private.h, so we just
@ -794,15 +805,18 @@ PatchFile::Finish(int status)
backup_finish(mFile, status);
}
static int
LaunchCallbackApp(const char *cmdLine)
static void
LaunchCallbackApp(int argc, char **argv)
{
// Someone will probably tell me that using 'system' is a bad idea, but for
// now it seems like it fits the bill. It saves us from having to parse the
// command line in order to call execv, and it nicely blocks this process
// until the command line is finished executing.
return system(cmdLine);
#if defined(USE_EXECV)
execv(argv[0], argv);
#elif defined(XP_MACOSX)
LaunchChild(argc, argv);
#elif defined(XP_WIN)
_spawnv(_P_NOWAIT, argv[0], argv);
#else
# warning "Need implementaton of LaunchCallbackApp"
#endif
}
static void
@ -850,19 +864,25 @@ int main(int argc, char **argv)
{
InitProgressUI(&argc, &argv);
// The updater command line consists of the directory path containing the
// updater.mar file to process followed by the PID of the calling process.
// The updater will wait on the parent process to exit if the PID is non-
// zero. This is leveraged on platforms such as Windows where it is
// necessary for the parent process to exit before its executable image may
// be altered.
if (argc < 3) {
fprintf(stderr, "Usage: updater <dir-path> <callback> [parent-pid]\n");
fprintf(stderr, "Usage: updater <dir-path> <parent-pid> [callback args...]\n");
return 1;
}
if (argc > 3) {
int pid = atoi(argv[3]);
if (!pid)
return 1;
int pid = atoi(argv[2]);
if (pid) {
#ifdef XP_WIN
HANDLE parent = OpenProcess(SYNCHRONIZE, FALSE, (DWORD) pid);
// May return NULL if the parent process has already gone away. Otherwise,
// wait for the parent process to exit before starting the update.
// May return NULL if the parent process has already gone away.
// Otherwise, wait for the parent process to exit before starting the
// update.
if (parent) {
DWORD result = WaitForSingleObject(parent, 5000);
CloseHandle(parent);
@ -892,7 +912,12 @@ int main(int argc, char **argv)
LogFinish();
return LaunchCallbackApp(argv[2]);
// The callback to execute is given as the last N arguments of our command
// line.
if (argc > 3)
LaunchCallbackApp(argc - 3, argv + 3);
return 0;
}
class ActionList