What is wrong with using wcmd and extending it if necessary? Chris
> > From: "Jaco Greeff" <[EMAIL PROTECTED]> > Date: 2002/10/31 Thu PM 04:27:43 EST > To: [EMAIL PROTECTED] > 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); > } > > > >