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@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.@) *