RFC: msvcrt _popen/_wpopen/_pclose
chrismorgan at rcn.com
chrismorgan at rcn.com
Thu Oct 31 15:47:15 CST 2002
What is wrong with using wcmd and extending it if necessary?
Chris
>
> From: "Jaco Greeff" <jaco at puxedo.org>
> Date: 2002/10/31 Thu PM 04:27:43 EST
> To: wine-devel at winehq.com
> Subject: RFC: msvcrt _popen/_wpopen/_pclose
>
> Hi,
>
> I want some comments on the possibility of a _popen/_wpopen/_pclose
> implementation in Wine. Reference available at:
>
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__popen.2c_._wpopen.asp
>
> The open functions basically operate in the same way as the popen function
> in Linux, ie. it spawns a process with the command via the command
> interpreter. Now, unfortionately we don't have our won cmd.exe available,
> but should people really need this functionality it might not be too much to
> ask as to copy it from a working Windows installation.
>
> In my mind, supporting the Win 95/98 command interpreters might be a
> nightmare - my gutt feel is that these two rely too much on DOS internals to
> be sucessfully launched via Wine. No, I haven't tried it, so I might be
> completely wrong. Either way, something like this might be better
> implemented via the Win NT/2000/XP cmd.exe. (I'll test my assumptions
> tomorrow, I don't have access to the command interpreters tonight.)
>
> I've hacked (yes, it was quick) a potential implementation of the _popen
> family of functions. (Haven't compiled, haven't tested, this is just and RFC
> - if it can work, I'll spend some real time on it.) Anyway, here it is,
> comments appreciated:
>
> --[ inline-ish RFC ]----
>
> #include "config.h"
> #include "wine/port.h"
>
> #include <stdio.h>
> #include <stdlib.h>
> #ifdef HAVE_UNISTD_H
> # include <unistd.h>
> #endif
>
> #include "winbase.h"
> #include "winnls.h"
> #include "wine/unicode.h"
> #include "msvcrt/stdio.h"
> #include "msvcrt/string.h"
>
> #include "wine/debug.h"
>
> #define POPEN_FLAG_READ 0x0001
> #define POPEN_FLAG_WRITE 0x0002
> #define POPEN_FLAG_TEXT 0x0004
> #define POPEN_FLAG_BINARY 0x0008
>
> inline CHAR *LPCWSTRToLPSTR(const LPCWSTR lpwstrIn, INT nIn)
> {
> INT nLen = WideCharToMultiByte(CP_ACP, 0, lpwszIn, nIn, NULL, 0, NULL,
> NULL);
> CHAR *szOut = (CHAR *)malloc((nLen+1)*sizeof(CHAR));
> if (szOut)
> {
> WideCharToMultiByte(CP_ACP, 0, lpwszIn, nIn, szOut, nLen+1, NULL, NULL);
> szOut[nLen] = '\0';
> }
> return szOut;
> }
>
> INT POPEN_parseModeFlags(const CHAR *szMode)
> {
> INT nFlags = 0;
> while (szMode && *szMode)
> {
> switch (*szMode)
> {
> case 'r':
> {
> if (nFlags & POPEN_FLAG_WRITE)
> WARN(": _popen: Cannot set both read and write open
> flags, ignoring read flag\n");
> else
> nFlags = nFlags & POPEN_FLAG_READ;
> break;
> }
> case 'w':
> {
> if (nFlags & POPEN_FLAG_READ)
> WARN(": _popen: Cannot set both read and write open
> flags, ignoring write flag\n");
> else
> nFlags = nFlags & POPEN_FLAG_WRITE;
> break;
> }
> case 'b':
> case 't':
> {
> FIXME(": _popen: %c mode flag not implemented, ignoring\n",
> *szMode);
> break;
> }
> default:
> {
> WARN(": _popen: unknown mode flag %c, ignoring\n", *szMode);
> break;
> }
> }
> }
> return nFlags;
> }
>
> MSVCRT_FILE *MSVCRT_popen(const CHAR *szCommand, const CHAR *szMode)
> {
> MSVCRT_FILE *fProcess = NULL;
>
> if (!szCommand || !szMode)
> return NULL;
>
> INT nFlags = POPEN_parseModeFlags(szMode);
> if (!(nFlags & (POPEN_FLAG_READ|POPEN_FLAG_WRITE)))
> {
> ERR("No open mode flag r or w specified\n");
> return NULL;
> }
>
> /* _popen/_wpopen executes the required command via the command
> * processor, either command.com (Win 95/98) or cmd.exe (Win NT/2000/XP).
> * Wine does not currently have it's own "cmd.exe" hence we cannot
> * really do anything more at this point. However, we try to lauch it
> * and hope for the best...
> */
> CHAR *szExec = (CHAR *)malloc(strlen("wine -- C:/cmd.exe -C
> ")+strlen(szCommand)+1);
> if (szExec)
> {
> sprintf(szExec, "wine -- C:/cmd.exe -C %s", szCommand);
> fProcess = popen(szExec, (nFlags & POPEN_FLAG_READ) ? "r" : "w");
> if (!fProcess)
> ERR("Execution of C:/cmd.exe via wine failed\n");
> else
> WARN("Launch of %s succeeded, no guarentees of success made\n",
> debugstr_a(szExec));
> free(szExec);
> }
>
> return fProcess;
> }
>
> MSVCRT_FILE *MSVCRT_wpopen(const WCHAR *wszCommand, const WCHAR *wszMode)
> {
> MSVCRT_FILE *fProcess = NULL;
>
> if (!wszCommand || !wszMode)
> return NULL;
>
> CHAR *szCommand = LPCWSTRToLPSTR(wszCommand, strlenW(wszCommand));
> if (szCommand)
> {
> CHAR *szMode = LPCWSTRToLPSTR(wszMode, strlenW(wszMode));
> if (szMode)
> {
> fProcess = _popen(szCommand, szMode);
> free(szMode);
> free(szCommand);
> }
> free(szCommand);
> }
>
> return fProcess;
> }
>
> int MSVCRT_pclose(MSVCRT_FILE *fProcess)
> {
> if (!fProcess)
> return -1;
> return pclose(fProcess);
> }
>
>
>
>
More information about the wine-devel
mailing list