summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2002-01-12 01:06:32 +0000
committerwtc%netscape.com <devnull@localhost>2002-01-12 01:06:32 +0000
commitb5907e7dcb74c70fe2aa413cc6bec773b93a917c (patch)
treeb9830c7f2fba5b42dceb0f64a9a1348160a5a770
parent6f2eb08b88173f282ab23c0ac6644cb24b28a50c (diff)
downloadnspr-hg-b5907e7dcb74c70fe2aa413cc6bec773b93a917c.tar.gz
Checked in the fix for bug 118631 on the NSPRPUB_PRE_4_2_CLIENT_BRANCH.
-rw-r--r--pr/src/md/os2/os2misc.c254
1 files changed, 139 insertions, 115 deletions
diff --git a/pr/src/md/os2/os2misc.c b/pr/src/md/os2/os2misc.c
index be597fcd..2c8a9b56 100644
--- a/pr/src/md/os2/os2misc.c
+++ b/pr/src/md/os2/os2misc.c
@@ -128,7 +128,7 @@ static int assembleCmdLine(char *const *argv, char **cmdLine)
* Find out how large the command line buffer should be.
*/
cmdLineSize = 0;
- for (arg = argv; *arg; arg++) {
+ for (arg = argv+1; *arg; arg++) {
/*
* \ and " need to be escaped by a \. In the worst case,
* every character is a \ or ", so the string of length
@@ -146,7 +146,7 @@ static int assembleCmdLine(char *const *argv, char **cmdLine)
return -1;
}
- for (arg = argv; *arg; arg++) {
+ for (arg = argv+1; *arg; arg++) {
/* Add a space to separates the arguments */
if (arg > argv + 1) {
*p++ = ' ';
@@ -213,11 +213,10 @@ static int assembleCmdLine(char *const *argv, char **cmdLine)
*p++ = '"';
}
if(arg == argv)
- *p++ = '\0';
+ *p++ = ' ';
}
- /* Add 2 nulls at the end */
- *p++ = '\0';
+ /* Add a null at the end */
*p = '\0';
return 0;
}
@@ -308,129 +307,154 @@ static int compare(const void *arg1, const void *arg2)
{
return stricmp(* (char**)arg1, * (char**)arg2);
}
+
PRProcess * _PR_CreateOS2Process(
const char *path,
char *const *argv,
char *const *envp,
const PRProcessAttr *attr)
{
- char szFailed[CCHMAXPATH];
- RESULTCODES procInfo;
- APIRET retVal;
- char *cmdLine = NULL;
- char *envBlock = NULL;
- char **newEnvp;
- PRProcess *proc = NULL;
- HFILE hStdIn = 0,
- hStdOut = 0,
- hStdErr = 0;
- HFILE hStdInSave = -1,
- hStdOutSave = -1,
- hStdErrSave = -1;
-
- proc = PR_NEW(PRProcess);
- if (!proc) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- goto errorExit;
- }
-
- if (assembleCmdLine(argv, &cmdLine) == -1) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- goto errorExit;
- }
-
- if (envp == NULL) {
- newEnvp = NULL;
- } else {
- int i;
- int numEnv = 0;
- while (envp[numEnv]) {
- numEnv++;
- }
- newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
- for (i = 0; i <= numEnv; i++) {
- newEnvp[i] = envp[i];
- }
- qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
- }
- if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- goto errorExit;
- }
-
- if (attr) {
- /* On OS/2, there is really no way to pass file handles for stdin, stdout,
- * and stderr to a new process. Instead, we can make it a child process
- * and make the given file handles a copy of our stdin, stdout, and stderr.
- * The child process then inherits ours, and we set ours back. Twisted
- * and gross I know. If you know a better way, please use it.
- */
- if (attr->stdinFd) {
- hStdIn = 0;
- DosDupHandle(hStdIn, &hStdInSave);
- DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
- }
- if (attr->stdoutFd) {
- hStdOut = 1;
- DosDupHandle(hStdOut, &hStdOutSave);
- DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
+ PRProcess *proc = NULL;
+ char *cmdLine = NULL;
+ char **newEnvp;
+ char *envBlock = NULL;
+
+ STARTDATA startData = {0};
+ APIRET rc;
+ ULONG ulAppType = 0;
+ PID pid = 0;
+ char *pEnvWPS = NULL;
+ char *pszComSpec;
+ char pszEXEName[CCHMAXPATH] = "";
+ char pszFormatString[CCHMAXPATH];
+ char pszObjectBuffer[CCHMAXPATH];
+ char *pszFormatResult = NULL;
+
+ proc = PR_NEW(PRProcess);
+ if (!proc) {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ goto errorExit;
+ }
+
+ if (assembleCmdLine(argv, &cmdLine) == -1) {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ goto errorExit;
+ }
+
+ if (envp == NULL) {
+ newEnvp = NULL;
+ } else {
+ int i;
+ int numEnv = 0;
+ while (envp[numEnv]) {
+ numEnv++;
}
- if (attr->stderrFd) {
- hStdErr = 2;
- DosDupHandle(hStdErr, &hStdErrSave);
- DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
+ newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
+ for (i = 0; i <= numEnv; i++) {
+ newEnvp[i] = envp[i];
}
- }
-
- retVal = DosExecPgm(szFailed,
- CCHMAXPATH,
- EXEC_ASYNCRESULT,
- cmdLine,
- envBlock,
- &procInfo,
- argv[0]);
-
- /* Restore our old values. Hope this works */
- if(hStdInSave != -1){
- DosDupHandle(hStdInSave, &hStdIn);
- DosClose(hStdInSave);
- }
- if(hStdOutSave != -1){
- DosDupHandle(hStdOutSave, &hStdOut);
- DosClose(hStdOutSave);
- }
- if(hStdErrSave != -1){
- DosDupHandle(hStdErrSave, &hStdErr);
- DosClose(hStdErrSave);
- }
+ qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
+ }
+ if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ goto errorExit;
+ }
+
+ if (attr) {
+ PR_ASSERT(!"Not implemented");
+ }
- if (retVal != NO_ERROR) {
- /* XXX what error code? */
- PR_SetError(PR_UNKNOWN_ERROR, retVal);
+ rc = DosQueryAppType(path, &ulAppType);
+ if (rc != NO_ERROR) {
+ char *pszDot = strrchr(path, '.');
+ if (pszDot) {
+ /* If it is a CMD file, launch the users command processor */
+ if (!stricmp(pszDot, ".cmd")) {
+ rc = DosScanEnv("COMSPEC", &pszComSpec);
+ if (!rc) {
+ strcpy(pszFormatString, "/C %s %s");
+ strcpy(pszEXEName, pszComSpec);
+ ulAppType = FAPPTYP_WINDOWCOMPAT;
+ }
+ }
+ }
+ }
+ if (ulAppType == 0) {
+ PR_SetError(PR_UNKNOWN_ERROR, 0);
goto errorExit;
- }
-
- proc->md.pid = procInfo.codeTerminate;
+ }
+
+ if (ulAppType & FAPPTYP_WINDOWAPI) {
+ startData.SessionType = SSF_TYPE_PM;
+ }
+ else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
+ startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
+ }
+ else {
+ startData.SessionType = SSF_TYPE_DEFAULT;
+ }
+
+ if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
+ {
+ strcpy(pszEXEName, "WINOS2.COM");
+ startData.SessionType = PROG_31_STDSEAMLESSVDM;
+ strcpy(pszFormatString, "/3 %s %s");
+ }
+
+ startData.InheritOpt = SSF_INHERTOPT_PARENT;
+
+ if (pszEXEName[0]) {
+ pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
+ sprintf(pszFormatResult, pszFormatString, path, cmdLine);
+ startData.PgmInputs = pszFormatResult;
+ } else {
+ strcpy(pszEXEName, path);
+ startData.PgmInputs = cmdLine;
+ }
+ startData.PgmName = pszEXEName;
+
+ startData.Length = sizeof(startData);
+ startData.Related = SSF_RELATED_CHILD;
+ startData.ObjectBuffer = pszObjectBuffer;
+ startData.ObjectBuffLen = CCHMAXPATH;
+ startData.Environment = envBlock;
+
+ rc = DosStartSession(&startData, &ulAppType, &pid);
+
+ if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
+ PR_SetError(PR_UNKNOWN_ERROR, 0);
+ }
+
+ proc->md.pid = pid;
- PR_DELETE(cmdLine);
- if (envBlock) {
- PR_DELETE(envBlock);
- }
- return proc;
+ if (pszFormatResult) {
+ PR_DELETE(pszFormatResult);
+ }
+
+ PR_DELETE(cmdLine);
+ if (newEnvp) {
+ PR_DELETE(newEnvp);
+ }
+ if (envBlock) {
+ PR_DELETE(envBlock);
+ }
+ return proc;
errorExit:
- if (cmdLine) {
- PR_DELETE(cmdLine);
- }
- if (envBlock) {
- PR_DELETE(envBlock);
- }
- if (proc) {
- PR_DELETE(proc);
- }
- return NULL;
-
-} /* _PR_CreateWindowsProcess */
+ if (cmdLine) {
+ PR_DELETE(cmdLine);
+ }
+ if (newEnvp) {
+ PR_DELETE(newEnvp);
+ }
+ if (envBlock) {
+ PR_DELETE(envBlock);
+ }
+ if (proc) {
+ PR_DELETE(proc);
+ }
+ return NULL;
+} /* _PR_CreateOS2Process */
PRStatus _PR_DetachOS2Process(PRProcess *process)
{