From 4d63df0429daef646b869df04a47fbed99a6f62e Mon Sep 17 00:00:00 2001 From: "dbragg%netscape.com" Date: Fri, 19 Jan 2001 21:23:24 +0000 Subject: [PATCH] New interface for creating and managing processes. New feature for bug 62167. a=dougt sr=brendan --- xpcom/threads/nsIProcess.idl | 25 +++++ xpcom/threads/nsProcess.h | 54 ++++++++++ xpcom/threads/nsProcessCommon.cpp | 168 ++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 xpcom/threads/nsIProcess.idl create mode 100644 xpcom/threads/nsProcess.h create mode 100644 xpcom/threads/nsProcessCommon.cpp diff --git a/xpcom/threads/nsIProcess.idl b/xpcom/threads/nsIProcess.idl new file mode 100644 index 00000000000..4009baadb0d --- /dev/null +++ b/xpcom/threads/nsIProcess.idl @@ -0,0 +1,25 @@ +#include "nsIFile.idl" +#include "nsISupports.idl" + +[scriptable, uuid(3ed86dbe-d084-11d4-ba7a-00c04fa0d26b)] + +interface nsIProcess : nsISupports +{ + void init(in nsIFile executable); + void initWithPid(in unsigned long pid); + + void kill(); + void run(in boolean blocking, [array, size_is(count)] in string args, in unsigned long count, out unsigned long pid); + + readonly attribute nsIFile location; + readonly attribute unsigned long pid; + readonly attribute string processName; + readonly attribute unsigned long processSignature; + readonly attribute long exitValue; +}; + +%{C++ + +#define NS_PROCESS_CONTRACTID "@mozilla.org/process/util;1" +#define NS_PROCESS_CLASSNAME "Process Specification" +%} diff --git a/xpcom/threads/nsProcess.h b/xpcom/threads/nsProcess.h new file mode 100644 index 00000000000..c222cc07485 --- /dev/null +++ b/xpcom/threads/nsProcess.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Don Bragg + */ + +#ifndef _nsPROCESSWIN_H_ +#define _nsPROCESSWIN_H_ + +#include "nsIProcess.h" +#include "nsXPIDLString.h" +#include "prproces.h" + +#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(); + virtual ~nsProcess(); + +private: + nsCOMPtr mExecutable; + PRInt32 mExitValue; + nsXPIDLCString mTargetPath; + PRProcess *mProcess; + +}; + +#endif \ No newline at end of file diff --git a/xpcom/threads/nsProcessCommon.cpp b/xpcom/threads/nsProcessCommon.cpp new file mode 100644 index 00000000000..d70b0f76222 --- /dev/null +++ b/xpcom/threads/nsProcessCommon.cpp @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Don Bragg + */ + +/***************************************************************************** + * + * nsProcess is used to execute new processes and specify if you want to + * wait (blocking) or continue (non-blocking). + * + ***************************************************************************** + */ + +#include "nsCOMPtr.h" +#include "nsMemory.h" +#include "nsProcess.h" +#include "prtypes.h" +#include "prio.h" + +#include + +//-------------------------------------------------------------------// +// nsIProcess implementation +//-------------------------------------------------------------------// +NS_IMPL_ISUPPORTS1(nsProcess, nsIProcess) + +//Constructor +nsProcess::nsProcess():mExitValue(-1), + mProcess(nsnull) +{ + NS_INIT_ISUPPORTS(); +} + +nsProcess::~nsProcess() +{ +} + +NS_IMETHODIMP +nsProcess::Init(nsIFile* 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; + + //Store the nsIFile in mExecutable + mExecutable = executable; + //Get the path because it is needed by the NSPR process creation +#ifdef XP_WIN + rv = mExecutable->GetTarget(getter_Copies(mTargetPath)); + if (NS_FAILED(rv) || !mTargetPath ) +#endif + rv = mExecutable->GetPath(getter_Copies(mTargetPath)); + + return rv; +} + + +NS_IMETHODIMP +nsProcess::Run(PRBool blocking, const char **args, PRUint32 count, PRUint32 *pid) +{ + nsresult rv = NS_OK; + + // make sure that when we allocate we have 1 greater than the + // count since we need to null terminate the list for the argv to + // pass into PR_CreateProcess + char **my_argv = NULL; + my_argv = (char **)malloc(sizeof(char *) * (count + 2) ); + if (!my_argv) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // copy the args + PRUint32 i; + for (i=0; i < count; i++) { + my_argv[i+1] = NS_CONST_CAST(char*, args[i]); + } + // we need to set argv[0] to the program name. + my_argv[0] = NS_CONST_CAST(char*, mTargetPath.get()); + // null terminate the array + my_argv[count+1] = NULL; + + if (blocking) + { + mProcess = PR_CreateProcess(mTargetPath, my_argv, NULL, NULL); + if (mProcess) + rv = PR_WaitProcess(mProcess, &mExitValue); + } + else + rv = PR_CreateProcessDetached(mTargetPath, my_argv, NULL, NULL); + + // free up our argv + nsMemory::Free(my_argv); + + if (rv != PR_SUCCESS) + return NS_ERROR_FILE_EXECUTION_FAILED; + return NS_OK; +} + +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) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsProcess::GetProcessName(char** aProcessName) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsProcess::GetProcessSignature(PRUint32 *aProcessSignature) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsProcess::Kill() +{ + nsresult rv = NS_OK; + if (mProcess) + rv = PR_KillProcess(mProcess); + + return rv; +} + +NS_IMETHODIMP +nsProcess::GetExitValue(PRInt32 *aExitValue) +{ + *aExitValue = mExitValue; + + return NS_OK; +} +