зеркало из https://github.com/mozilla/pjs.git
trunk fix for 84115. Pass arguments to the process (I omitted these in an earlier
checkin). Bad because xpi files that invoke processes with args are not functioning correctly. r=ssu, sr=mscott, a=drivers (asa)
This commit is contained in:
Родитель
16951bbe32
Коммит
421006c67d
|
@ -39,6 +39,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#if defined( XP_WIN )
|
||||
#include "prmem.h"
|
||||
#include "nsString.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
@ -85,6 +86,110 @@ nsProcess::Init(nsIFile* executable)
|
|||
}
|
||||
|
||||
|
||||
#if defined( XP_WIN )
|
||||
static int assembleCmdLine(char *const *argv, char **cmdLine)
|
||||
{
|
||||
char *const *arg;
|
||||
char *p, *q;
|
||||
int cmdLineSize;
|
||||
int numBackslashes;
|
||||
int i;
|
||||
int argNeedQuotes;
|
||||
|
||||
/*
|
||||
* Find out how large the command line buffer should be.
|
||||
*/
|
||||
cmdLineSize = 0;
|
||||
for (arg = argv; *arg; arg++) {
|
||||
/*
|
||||
* \ and " need to be escaped by a \. In the worst case,
|
||||
* every character is a \ or ", so the string of length
|
||||
* may double. If we quote an argument, that needs two ".
|
||||
* Finally, we need a space between arguments, and
|
||||
* a null byte at the end of command line.
|
||||
*/
|
||||
cmdLineSize += 2 * strlen(*arg) /* \ and " need to be escaped */
|
||||
+ 2 /* we quote every argument */
|
||||
+ 1; /* space in between, or final null */
|
||||
}
|
||||
p = *cmdLine = (char *) PR_MALLOC(cmdLineSize);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (arg = argv; *arg; arg++) {
|
||||
/* Add a space to separates the arguments */
|
||||
if (arg != argv) {
|
||||
*p++ = ' ';
|
||||
}
|
||||
q = *arg;
|
||||
numBackslashes = 0;
|
||||
argNeedQuotes = 0;
|
||||
|
||||
/* If the argument contains white space, it needs to be quoted. */
|
||||
if (strpbrk(*arg, " \f\n\r\t\v")) {
|
||||
argNeedQuotes = 1;
|
||||
}
|
||||
|
||||
if (argNeedQuotes) {
|
||||
*p++ = '"';
|
||||
}
|
||||
while (*q) {
|
||||
if (*q == '\\') {
|
||||
numBackslashes++;
|
||||
q++;
|
||||
} else if (*q == '"') {
|
||||
if (numBackslashes) {
|
||||
/*
|
||||
* Double the backslashes since they are followed
|
||||
* by a quote
|
||||
*/
|
||||
for (i = 0; i < 2 * numBackslashes; i++) {
|
||||
*p++ = '\\';
|
||||
}
|
||||
numBackslashes = 0;
|
||||
}
|
||||
/* To escape the quote */
|
||||
*p++ = '\\';
|
||||
*p++ = *q++;
|
||||
} else {
|
||||
if (numBackslashes) {
|
||||
/*
|
||||
* Backslashes are not followed by a quote, so
|
||||
* don't need to double the backslashes.
|
||||
*/
|
||||
for (i = 0; i < numBackslashes; i++) {
|
||||
*p++ = '\\';
|
||||
}
|
||||
numBackslashes = 0;
|
||||
}
|
||||
*p++ = *q++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we are at the end of this argument */
|
||||
if (numBackslashes) {
|
||||
/*
|
||||
* Double the backslashes if we have a quote string
|
||||
* delimiter at the end.
|
||||
*/
|
||||
if (argNeedQuotes) {
|
||||
numBackslashes *= 2;
|
||||
}
|
||||
for (i = 0; i < numBackslashes; i++) {
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
if (argNeedQuotes) {
|
||||
*p++ = '"';
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProcess::Run(PRBool blocking, const char **args, PRUint32 count, PRUint32 *pid)
|
||||
{
|
||||
|
@ -113,12 +218,19 @@ nsProcess::Run(PRBool blocking, const char **args, PRUint32 count, PRUint32 *pid
|
|||
STARTUPINFO startupInfo;
|
||||
PROCESS_INFORMATION procInfo;
|
||||
BOOL retVal;
|
||||
char *cmdLine;
|
||||
|
||||
if (assembleCmdLine(my_argv, &cmdLine) == -1) {
|
||||
nsMemory::Free(my_argv);
|
||||
return NS_ERROR_FILE_EXECUTION_FAILED;
|
||||
}
|
||||
|
||||
ZeroMemory(&startupInfo, sizeof(startupInfo));
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
retVal = CreateProcess(NULL,
|
||||
NS_CONST_CAST(char*, mTargetPath.get()),
|
||||
// NS_CONST_CAST(char*, mTargetPath.get()),
|
||||
cmdLine,
|
||||
NULL, /* security attributes for the new
|
||||
* process */
|
||||
NULL, /* security attributes for the primary
|
||||
|
@ -130,7 +242,7 @@ nsProcess::Run(PRBool blocking, const char **args, PRUint32 count, PRUint32 *pid
|
|||
&startupInfo,
|
||||
&procInfo
|
||||
);
|
||||
|
||||
PR_FREEIF( cmdLine );
|
||||
if (blocking) {
|
||||
|
||||
// if success, wait for process termination. the early returns and such
|
||||
|
|
Загрузка…
Ссылка в новой задаче