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