Back out patch for bug 442393.
authorJames Boston <jamesboston@gmail.com>
Fri, 06 Mar 2009 16:42:07 -0600
changeset 25818 2b9ed1c47f4640984390f517acd2054ad9418bc1
parent 25817 a632978b885f1c1ceb80cf6c4a115107b869dc27
child 25819 356458e646d0c04c7d55a1f63194b9ede7d86215
push id5761
push userjosh@mozilla.com
push dateFri, 06 Mar 2009 22:40:16 +0000
treeherdermozilla-central@2b9ed1c47f46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs442393
milestone1.9.2a1pre
Back out patch for bug 442393.
xpcom/tests/Makefile.in
xpcom/tests/TestArguments.cpp
xpcom/tests/TestBlockingProcess.cpp
xpcom/tests/TestQuickReturn.cpp
xpcom/tests/unit/test_nsIProcess.js
xpcom/threads/nsIProcess.idl
xpcom/threads/nsProcess.h
xpcom/threads/nsProcessCommon.cpp
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -67,19 +67,16 @@ CPPSRCS		= \
 		TestCallTemplates.cpp \
 		TestINIParser.cpp \
 		TestVersionComparator.cpp \
 		TestRacingServiceManager.cpp \
 		TestRegistrationOrder.cpp \
 		TestThreadPoolListener.cpp \
 		TestTimers.cpp \
 		TestOOM.cpp \
-		TestBlockingProcess.cpp \
-		TestQuickReturn.cpp \
-		TestArguments.cpp \
 		$(NULL)
 
 ifndef MOZ_ENABLE_LIBXUL
 CPPSRCS += \
 		TestAtoms.cpp \
 		TestPermanentAtoms.cpp \
 		$(NULL)
 endif
deleted file mode 100644
--- a/xpcom/tests/TestArguments.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <iostream>
-#include <string>
-
-using namespace std;
-
-int main(int argc, char* argv[]) {
-
-  string test = "mozilla";
-
-  if (test.compare(argv[1]) != 0)
-      return -1;
-  
-  return 0;
-} 
deleted file mode 100644
--- a/xpcom/tests/TestBlockingProcess.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <stdio.h>
- 
-int main()
-{
-   char text[20];
-   fgets(text, sizeof text, stdin);
-   return 0;
-}
-
deleted file mode 100644
--- a/xpcom/tests/TestQuickReturn.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdio.h>
-
-int main () {
-  
-  return 42;
-}
deleted file mode 100644
--- a/xpcom/tests/unit/test_nsIProcess.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ***** 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 XPCOM unit tests.
- *
- * The Initial Developer of the Original Code is
- * James Boston <mozilla@jamesboston.ca>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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 ***** */
-// nsIProcess unit test
-
-// get the path to {objdir}/dist/bin
-var bindir = Components.classes["@mozilla.org/file/directory_service;1"]
-.getService(Components.interfaces.nsIProperties)
-.get("CurProcD", Components.interfaces.nsIFile);
-
-// the the os
-var isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
-
-var filePrefix = "";
-var fileSuffix = "";
-
-if (isWindows) {
-  filePrefix = bindir.path + "\\";
-  fileSuffix = ".exe";
-} else {
-  filePrefix = bindir.path + "/";
-}
-
-
-// test if a process can be started, polled for its running status
-// and then killed
-function test_kill()
-{
-  var testapp = filePrefix + "TestBlockingProcess" +fileSuffix;
-  print(testapp);
- 
-  var file = Components.classes["@mozilla.org/file/local;1"]
-                       .createInstance(Components.interfaces.nsILocalFile);
-  file.initWithPath(testapp);
- 
-  var process = Components.classes["@mozilla.org/process/util;1"]
-                          .createInstance(Components.interfaces.nsIProcess);
-  process.init(file);
-  
-  var pid = process.run(false, [], 0);
-
-  if (!pid) {
-    return false;
-  }
-
-  var rv = process.isRunning;
-
-  if (!rv) {    
-    return false;
-  }
-
-  process.kill();
-
-  rv = process.isRunning;
-
-  if (rv){
-    return false;
-  }
-  return true;
-
-}
-
-// test if we can get an exit value from an application that is
-// guaranteed to return an exit value of 42
-function test_quick()
-{
-  var testapp = filePrefix + "TestQuickReturn" + fileSuffix;
-  
-  var file = Components.classes["@mozilla.org/file/local;1"]
-  .createInstance(Components.interfaces.nsILocalFile);
-  file.initWithPath(testapp);
-  
-  var process = Components.classes["@mozilla.org/process/util;1"]
-  .createInstance(Components.interfaces.nsIProcess);
-  process.init(file);
-  
-  // to get an exit value it must be a blocking process
-  var pid = process.run(true, [], 0);
-  
-  if (!pid) {
-    return false;
-  }
-  
-  if (process.exitValue != 42) {
-    return false;
-  }
-  return true;
-}
-
-// test if an argument can be successfully passed to an application
-// that will return -1 if "mozilla" is not the first argument
-function test_arguments()
-{
-  var testapp = filePrefix + "TestArguments" + fileSuffix;
-  
-  var file = Components.classes["@mozilla.org/file/local;1"]
-  .createInstance(Components.interfaces.nsILocalFile);
-  file.initWithPath(testapp);
-  
-  var process = Components.classes["@mozilla.org/process/util;1"]
-  .createInstance(Components.interfaces.nsIProcess);
-  process.init(file);
-  
-  var args= ["mozilla"];
-  
-  var pid = process.run(true, args, args.length);
-  
-  if (!pid) {
-    return false;
-  }
-    
-  if (process.exitValue) {
-    return false;
-  }
-  return true;
-}
-
-function run_test() {
-  do_check_true(test_kill());
-  do_check_true(test_quick());
-  do_check_true(test_arguments());
-}
--- a/xpcom/threads/nsIProcess.idl
+++ b/xpcom/threads/nsIProcess.idl
@@ -1,12 +1,12 @@
 #include "nsIFile.idl"
 #include "nsISupports.idl"
 
-[scriptable, uuid(d573f1f3-fcdd-4dbe-980b-4ba79e6718dc)]
+[scriptable, uuid(9da0b650-d07e-4617-a18a-250035572ac8)]
 
 interface nsIProcess : nsISupports
 {
 	void init(in nsIFile executable);
 	void initWithPid(in unsigned long pid);
 	
 	void kill();
 
@@ -18,16 +18,15 @@ interface nsIProcess : nsISupports
          * @return the PID of the newly spawned process */
         unsigned long run(in boolean blocking, [array, size_is(count)] in string args, in unsigned long count);
 
 	readonly attribute nsIFile location;
 	readonly attribute unsigned long pid;
 	readonly attribute string processName;
 	readonly attribute unsigned long processSignature;
 	readonly attribute long exitValue;
-	readonly attribute unsigned long isRunning;
 };
 
 %{C++
 
 #define NS_PROCESS_CONTRACTID "@mozilla.org/process/util;1"
 #define NS_PROCESS_CLASSNAME "Process Specification"
 %}
--- a/xpcom/threads/nsProcess.h
+++ b/xpcom/threads/nsProcess.h
@@ -35,47 +35,37 @@
  * 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 ***** */
 
 #ifndef _nsPROCESSWIN_H_
 #define _nsPROCESSWIN_H_
 
-#if defined(XP_WIN) && !defined (WINCE) /* wince uses nspr */
-#define PROCESSMODEL_WINAPI
-#endif
-
 #include "nsIProcess.h"
 #include "nsIFile.h"
 #include "nsString.h"
 #include "prproces.h"
-#if defined(PROCESSMODEL_WINAPI) 
-#include <windows.h>
-#endif
 
 #define NS_PROCESS_CID \
 {0x7b4eeb20, 0xd781, 0x11d4, \
    {0x8A, 0x83, 0x00, 0x10, 0xa4, 0xe0, 0xc9, 0xca}}
 
 class nsProcess : public nsIProcess
 {
 public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPROCESS
 
   nsProcess();
 
 private:
-  ~nsProcess();
+  ~nsProcess() {}
 
   nsCOMPtr<nsIFile> mExecutable;
   PRInt32 mExitValue;
   nsCString mTargetPath;
   PRProcess *mProcess;
 
-#if defined(PROCESSMODEL_WINAPI) 
-  PROCESS_INFORMATION procInfo;
-#endif
 };
 
 #endif
--- a/xpcom/threads/nsProcessCommon.cpp
+++ b/xpcom/threads/nsProcessCommon.cpp
@@ -56,62 +56,38 @@
 #include <stdlib.h>
 
 #if defined(XP_WIN)
 #include "prmem.h"
 #include "nsString.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include <windows.h>
-#else
-#include <sys/types.h>
-#include <signal.h>
+#endif
+
+#if defined(XP_MACOSX)
+#include <Processes.h>
+#include "nsILocalFileMac.h"
 #endif
 
 //-------------------------------------------------------------------//
 // nsIProcess implementation
 //-------------------------------------------------------------------//
 NS_IMPL_ISUPPORTS1(nsProcess, nsIProcess)
 
 //Constructor
 nsProcess::nsProcess()
     : mExitValue(-1),
       mProcess(nsnull)
 {
-#if defined(PROCESSMODEL_WINAPI)
-    procInfo.dwProcessId = nsnull;
-#endif
-}
-
-//Destructor
-nsProcess::~nsProcess()
-{
-#if defined(PROCESSMODEL_WINAPI)
-    if (procInfo.dwProcessId) {
-        CloseHandle( procInfo.hProcess );
-        CloseHandle( procInfo.hThread );
-    }
-#else
-    if (mProcess) 
-        PR_DetachProcess(mProcess);
-#endif
 }
 
 NS_IMETHODIMP
 nsProcess::Init(nsIFile* executable)
 {
-    //Prevent re-initializing if already attached to process
-#if defined(PROCESSMODEL_WINAPI)
-    if (procInfo.dwProcessId)
-        return NS_ERROR_ALREADY_INITIALIZED;
-#else
-    if (mProcess)
-        return NS_ERROR_ALREADY_INITIALIZED;
-#endif    
-
     NS_ENSURE_ARG_POINTER(executable);
     PRBool isFile;
 
     //First make sure the file exists
     nsresult rv = executable->IsFile(&isFile);
     if (NS_FAILED(rv)) return rv;
     if (!isFile)
         return NS_ERROR_FAILURE;
@@ -260,18 +236,19 @@ nsProcess::Run(PRBool blocking, const ch
     for (i=0; i < count; i++) {
         my_argv[i+1] = const_cast<char*>(args[i]);
     }
     // we need to set argv[0] to the program name.
     my_argv[0] = mTargetPath.BeginWriting();
     // null terminate the array
     my_argv[count+1] = NULL;
 
-#if defined(PROCESSMODEL_WINAPI)
+#if defined(XP_WIN) && !defined (WINCE) /* wince uses nspr */
     STARTUPINFOW startupInfo;
+    PROCESS_INFORMATION procInfo;
     BOOL retVal;
     PRUnichar *cmdLine;
 
     if (assembleCmdLine(my_argv, &cmdLine) == -1) {
         nsMemory::Free(my_argv);
         return NS_ERROR_FILE_EXECUTION_FAILED;    
     }
 
@@ -293,17 +270,16 @@ nsProcess::Run(PRBool blocking, const ch
                                     * thread in the new process */
                             FALSE,  /* inherit handles */
                             CREATE_NO_WINDOW, /* creation flags */
                             NULL,  /* env */
                             NULL,  /* current drive and directory */
                             &startupInfo,
                             &procInfo
                            );
-    *pid = procInfo.dwProcessId;
     PR_Free( cmdLine );
     if (blocking) {
  
         // if success, wait for process termination. the early returns and such
         // are a bit ugly but preserving the logic of the nspr code I copied to 
         // minimize our risk abit.
 
         if ( retVal == TRUE ) {
@@ -318,108 +294,125 @@ nsProcess::Run(PRBool blocking, const ch
             if (GetExitCodeProcess(procInfo.hProcess, &exitCode) == FALSE) {
                 mExitValue = exitCode;
                 nsMemory::Free(my_argv);
                return NS_ERROR_FAILURE;
             }
             mExitValue = exitCode;
             CloseHandle(procInfo.hProcess);
             CloseHandle(procInfo.hThread);
-            procInfo.dwProcessId = nsnull;
         }
         else
             status = PR_FAILURE;
     } 
     else {
 
         // map return value into success code
 
         if (retVal == TRUE) 
             status = PR_SUCCESS;
         else
             status = PR_FAILURE;
     }
 
 #else // Note, this must not be an #elif ...!
-    
-    mProcess = PR_CreateProcess(mTargetPath.get(), my_argv, NULL, NULL);
-    if (mProcess) {
-        GetPid(pid);
-        status = PR_SUCCESS;
+
+#if defined(XP_MACOSX)
+    if (count == 0) {
+        FSSpec resolvedSpec;
+        OSErr err = noErr;
+
+        nsCOMPtr<nsILocalFileMac> macExecutable =
+            do_QueryInterface(mExecutable);
+        macExecutable->GetFSSpec(&resolvedSpec);
+
+        LaunchParamBlockRec launchPB;
+        launchPB.launchAppSpec = &resolvedSpec;
+        launchPB.launchAppParameters = NULL;
+        launchPB.launchBlockID = extendedBlock;
+        launchPB.launchEPBLength = extendedBlockLen;
+        launchPB.launchFileFlags = NULL;
+        launchPB.launchControlFlags =
+            launchContinue + launchNoFileFlags + launchUseMinimum;
+        if (!blocking)
+            launchPB.launchControlFlags += launchDontSwitch;
+
+        err = LaunchApplication(&launchPB);
+
+        // NOTE: blocking mode assumes you are running on a thread
+        //       other than the UI thread that has the main event loop
+        if (blocking && err == noErr) {
+            while (1) {
+                ProcessInfoRec info;
+                info.processInfoLength = sizeof(ProcessInfoRec);
+                info.processName = NULL;
+                info.processAppSpec = NULL;
+
+                err = GetProcessInformation(&launchPB.launchProcessSN, &info);
+
+                if (err != noErr) {
+                    // The process is no longer in the process
+                    // manager's internal list, assume the process is
+                    // done.
+                    err = noErr;
+
+                    break;
+                }
+
+                // still running so sleep some more (200 msecs)
+                PR_Sleep(200);
+            }
+        }
+
+        if (err != noErr) {
+            status = PR_FAILURE;
+        }
+
         if (blocking) {
-            status = PR_WaitProcess(mProcess, &mExitValue);
-            mProcess = nsnull;
-        } 
+            mExitValue = err;
+        }
+    } else
+#endif
+    {
+        if (blocking) {
+            mProcess = PR_CreateProcess(mTargetPath.get(), my_argv, NULL,
+                                        NULL);
+            if (mProcess)
+                status = PR_WaitProcess(mProcess, &mExitValue);
+        } else {
+            status = PR_CreateProcessDetached(mTargetPath.get(), my_argv, NULL,
+                                          NULL);
+        }
     }
 #endif
 
     // free up our argv
     nsMemory::Free(my_argv);
 
     if (status != PR_SUCCESS)
         return NS_ERROR_FILE_EXECUTION_FAILED;
 
     return NS_OK;
 }
 
-NS_IMETHODIMP nsProcess::GetIsRunning(PRUint32 *aIsRunning)
-{
-#if defined(PROCESSMODEL_WINAPI)
-    DWORD ec = 0;
-    BOOL br = GetExitCodeProcess(procInfo.hProcess, &ec);
-    if (!br) {
-        aIsRunning = 0;
-        return NS_OK;
-    }
-    *aIsRunning = (ec == STILL_ACTIVE ? 1 : 0); 
-    return NS_OK;
-#elif defined WINCE
-    return NS_ERROR_NOT_IMPLEMENTED;   
-#else
-    PRUint32 pid;
-    GetPid(&pid);
-    if (pid)
-        *aIsRunning = (kill(pid, 0) != -1) ? 1 : 0;
-    return NS_OK;        
-#endif
-}
-
 NS_IMETHODIMP nsProcess::InitWithPid(PRUint32 pid)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsProcess::GetLocation(nsIFile** aLocation)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsProcess::GetPid(PRUint32 *aPid)
 {
-#if defined(PROCESSMODEL_WINAPI)
-    if (!procInfo.dwProcessId)
-        return NS_ERROR_FAILURE;
-    *aPid = procInfo.dwProcessId;
-    return NS_OK;
-#elif defined WINCE
     return NS_ERROR_NOT_IMPLEMENTED;
-#else
-    if (!mProcess) {
-        *aPid = 0;
-        return NS_ERROR_FAILURE;
-    }
-    struct MYProcess {
-        PRUint32 pid;
-    };
-    MYProcess* ptrProc = (MYProcess *) mProcess;
-    *aPid = ptrProc->pid;
-    return NS_OK;
-#endif
 }
 
 NS_IMETHODIMP
 nsProcess::GetProcessName(char** aProcessName)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -428,30 +421,19 @@ nsProcess::GetProcessSignature(PRUint32 
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsProcess::Kill()
 {
     nsresult rv = NS_OK;
-#if defined(PROCESSMODEL_WINAPI)
-    if ( TerminateProcess(procInfo.hProcess, NULL) == 0 ) {
-        rv = NS_ERROR_FAILURE;
-    }
-    else {
-        CloseHandle( procInfo.hProcess );
-        procInfo.dwProcessId = nsnull;
-    }
-#else
     if (mProcess)
         rv = PR_KillProcess(mProcess) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
-    if (rv == NS_OK)
-        mProcess = nsnull;
-#endif  
+    
     return rv;
 }
 
 NS_IMETHODIMP
 nsProcess::GetExitValue(PRInt32 *aExitValue)
 {
     *aExitValue = mExitValue;