msvcrt-A06: _popen + COMSPEC
Jaco Greeff
jaco at puxedo.org
Sun Nov 3 09:38:13 CST 2002
This msvcrt-A?? series patch extends the _popen function
to look at the COMSPEC env. variable to determine the
command interpreter to use in _popen/_wpopen. If COMSPEC
is not set, or not found on disk, _popen makes use of
c:\windows\system32\cmd.exe binary.
License:
LGPL
Changelog:
* dlls/msvcrt/file.c:
Jaco Greeff <jaco at puxedo.org>
- Extention of _popen to read the COMSPEC variable to find the
command interpreter.
--[ inline patch ]--
diff -aurN msvcrt-A05/dlls/msvcrt/file.c msvcrt-A06/dlls/msvcrt/file.c
--- msvcrt-A05/dlls/msvcrt/file.c 2002-11-03 14:11:35.000000000 +0000
+++ msvcrt-A06/dlls/msvcrt/file.c 2002-11-03 14:56:02.000000000 +0000
@@ -103,7 +103,10 @@
#define POPEN_MAX_FILES 10
#define POPEN_FILE_IN_USE 0x0001
-#define POPEN_WCMD_EXEC "C:\\Windows\\System32\\cmd.exe /c"
+/* If we cannot find the interpretedr pointed to by COMSPEC,
+ * this is the interpreter we will try to use
+ */
+#define POPEN_WCMD_EXEC "C:\\Windows\\System32\\cmd.exe"
typedef struct
{
@@ -2360,6 +2363,7 @@
return nFlags;
}
+
/*********************************************************************
* POPEN_getOpenFileSlotPos (internal)
*
@@ -2381,6 +2385,7 @@
return -1;
}
+
/*********************************************************************
* POPEN_findFileSlotPos (internal)
*
@@ -2399,10 +2404,64 @@
return -1;
}
+
+/*********************************************************************
+ * POPEN_getInterpreterCmd (internal)
+ *
+ * Description
+ * Finds an interpreter to use and combines this with the command
+ * we are to execute via _popen. If COMSPEC is set an a valid
+ * interpreter is found for it, it will be used, else it will
+ * use POPEN_WCMD_EXEC
+ *
+ * Input
+ * szCommand - Command to execute via the interpreter, as passed
+ * to _popen/_wpopen
+ *
+ * Output
+ * The full command string or NULL on failure
+ */
+static CHAR *POPEN_getInterpreterCmd(const CHAR *szCommand)
+{
+ CHAR szInterpreter[1024+1];
+ CHAR *szExec = NULL;
+
+ /* Get the value of COMSPEC, if not available, fall back to
+ * our hard-coded default
+ */
+ if (!(GetEnvironmentVariableA("COMSPEC", szInterpreter, 1024)) ||
+ (GetFileAttributesA(szInterpreter) == -1))
+ {
+ if ((GetFileAttributesA(POPEN_WCMD_EXEC) != -1))
+ snprintf(szInterpreter, 1024, "%s", POPEN_WCMD_EXEC);
+ else
+ {
+ TRACE("No available command interpreters or COMSPEC not set\n");
+ return NULL;
+ }
+ }
+
+ TRACE("Using interpreter == %s\n", szInterpreter);
+
+ /* _popen/_wpopen executes the required command via the command
+ * processor, so we will need to set the interpreter to execute
+ * and return, the "/c" flag
+ */
+ if ((szExec = (CHAR *)MSVCRT_malloc(strlen(szInterpreter)+strlen(" /c
")+strlen(szCommand)+1)))
+ sprintf(szExec, "%s /c %s", szInterpreter, szCommand);
+ else
+ TRACE("Unable to allocate memory for process command line\n");
+
+ return szExec;
+}
+
+
/*********************************************************************
* MSVCRT_popen (MSVCRT.@)
*
* Description
+ * Opens a process, returning a FILE structure to allow reading
+ * from or writing to the process.
*
* Input
* szCommand - The command to execute, this gets executed as
@@ -2483,11 +2542,11 @@
else
TRACE("Duplication of handle failed\n");
- /* _popen/_wpopen executes the required command via the command
- * processor, either command.com (Win 95/98) or cmd.exe (Win NT/2000/XP).
- * wcmd acts as a replacement, so we will be launching it instead.
+
+ /* Try to get the system interpreter, if this fails,
+ * gracefully clean up and exit
*/
- if (!(szExec = (CHAR *)MSVCRT_malloc(strlen(POPEN_WCMD_EXEC)+strlen("
")+strlen(szCommand)+1)))
+ if (!(szExec = POPEN_getInterpreterCmd(szCommand)))
{
SetStdHandle(STD_INPUT_HANDLE, hOrigIn);
SetStdHandle(STD_OUTPUT_HANDLE, hOrigOut);
@@ -2495,11 +2554,8 @@
CloseHandle(hNewOutReadDup);
CloseHandle(hNewInRead);
CloseHandle(hNewInWriteDup);
-
- TRACE("Unable to allocate memory for process command line\n");
return NULL;
}
- sprintf(szExec, "%s %s", POPEN_WCMD_EXEC, szCommand);
/* create the process with our attributes, using the
* redirected stream we just setup
@@ -2572,6 +2628,7 @@
return fProcess;
}
+
/*********************************************************************
* POPEN_LPCWSTRToLPSTR (internal)
*
@@ -2598,6 +2655,7 @@
return szOut;
}
+
/*********************************************************************
* MSVCRT_wpopen (MSVCRT.@)
*
@@ -2631,6 +2689,7 @@
return fProcess;
}
+
/*********************************************************************
* MSVCRT_pclose (MSVCRT.@)
*
More information about the wine-patches
mailing list