Module: wine Branch: master Commit: 118bee860a3108ce3ab01823dc93d4f186ecba77 URL: http://source.winehq.org/git/wine.git/?a=commit;h=118bee860a3108ce3ab01823dc...
Author: Hans Leidekker hans@it.vu.nl Date: Mon Jan 7 14:22:36 2008 +0100
msvcrt: Implement _wpopen and forward _popen to it.
---
dlls/msvcrt/msvcrt.h | 1 + dlls/msvcrt/process.c | 69 ++++++++++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 26 deletions(-)
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 59c42cb..bc94284 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -623,6 +623,7 @@ MSVCRT_clock_t MSVCRT_clock(void); double MSVCRT_difftime(MSVCRT_time_t time1, MSVCRT_time_t time2); MSVCRT_time_t MSVCRT_time(MSVCRT_time_t*); MSVCRT_FILE* MSVCRT__fdopen(int, const char *); +MSVCRT_FILE* MSVCRT__wfdopen(int, const MSVCRT_wchar_t *); int MSVCRT_vsnprintf(char *str, unsigned int len, const char *format, va_list valist); int MSVCRT_vsnwprintf(MSVCRT_wchar_t *str, unsigned int len, const MSVCRT_wchar_t *format, va_list valist ); diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c index 46481ef..2db9a7d 100644 --- a/dlls/msvcrt/process.c +++ b/dlls/msvcrt/process.c @@ -721,22 +721,21 @@ MSVCRT_intptr_t CDECL _wspawnvp(int flags, const MSVCRT_wchar_t* name, const MSV }
/********************************************************************* - * _popen (MSVCRT.@) - * FIXME: convert to _wpopen and call that from here instead? But it - * would have to convert the command back to ANSI to call msvcrt_spawn, - * less than ideal. + * _wpopen (MSVCRT.@) + * + * Unicode version of _popen */ -MSVCRT_FILE* CDECL MSVCRT__popen(const char* command, const char* mode) +MSVCRT_FILE* CDECL MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wchar_t* mode) { - static const char wcmd[] = "cmd", cmdFlag[] = " /C ", comSpec[] = "COMSPEC"; MSVCRT_FILE *ret; BOOL readPipe = TRUE; int textmode, fds[2], fdToDup, fdToOpen, fdStdHandle = -1, fdStdErr = -1; - const char *p; - char *cmdcopy; - DWORD comSpecLen; + const MSVCRT_wchar_t *p; + MSVCRT_wchar_t *comspec, *fullcmd; + unsigned int len; + static const MSVCRT_wchar_t flag[] = {' ','/','c',' ',0};
- TRACE("(command=%s, mode=%s)\n", debugstr_a(command), debugstr_a(mode)); + TRACE("(command=%s, mode=%s)\n", debugstr_w(command), debugstr_w(mode));
if (!command || !mode) return NULL; @@ -782,27 +781,27 @@ MSVCRT_FILE* CDECL MSVCRT__popen(const char* command, const char* mode)
MSVCRT__close(fds[fdToDup]);
- comSpecLen = GetEnvironmentVariableA(comSpec, NULL, 0); - if (!comSpecLen) - comSpecLen = strlen(wcmd) + 1; - cmdcopy = HeapAlloc(GetProcessHeap(), 0, comSpecLen + strlen(cmdFlag) - + strlen(command)); - if (!GetEnvironmentVariableA(comSpec, cmdcopy, comSpecLen)) - strcpy(cmdcopy, wcmd); - strcat(cmdcopy, cmdFlag); - strcat(cmdcopy, command); - if (msvcrt_spawn(MSVCRT__P_NOWAIT, NULL, cmdcopy, NULL) == -1) + if (!(comspec = msvcrt_get_comspec())) goto error; + len = strlenW(comspec) + strlenW(flag) + strlenW(command) + 1; + + if (!(fullcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t)))) goto error; + strcpyW(fullcmd, comspec); + strcatW(fullcmd, flag); + strcatW(fullcmd, command); + HeapFree(GetProcessHeap(), 0, comspec); + + if (msvcrt_spawn_wide(MSVCRT__P_NOWAIT, NULL, fullcmd, NULL) == -1) { MSVCRT__close(fds[fdToOpen]); ret = NULL; } else { - ret = MSVCRT__fdopen(fds[fdToOpen], mode); + ret = MSVCRT__wfdopen(fds[fdToOpen], mode); if (!ret) MSVCRT__close(fds[fdToOpen]); } - HeapFree(GetProcessHeap(), 0, cmdcopy); + HeapFree(GetProcessHeap(), 0, fullcmd); MSVCRT__dup2(fdStdHandle, fdToDup); MSVCRT__close(fdStdHandle); if (readPipe) @@ -821,12 +820,30 @@ error: }
/********************************************************************* - * _wpopen (MSVCRT.@) + * _popen (MSVCRT.@) */ -MSVCRT_FILE* CDECL MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wchar_t* mode) +MSVCRT_FILE* CDECL MSVCRT__popen(const char* command, const char* mode) { - FIXME("(command=%s, mode=%s): stub\n", debugstr_w(command), debugstr_w(mode)); - return NULL; + MSVCRT_FILE *ret; + MSVCRT_wchar_t *cmdW, *modeW; + + TRACE("(command=%s, mode=%s)\n", debugstr_a(command), debugstr_a(mode)); + + if (!command || !mode) + return NULL; + + if (!(cmdW = msvcrt_wstrdupa(command))) return NULL; + if (!(modeW = msvcrt_wstrdupa(mode))) + { + HeapFree(GetProcessHeap(), 0, cmdW); + return NULL; + } + + ret = MSVCRT__wpopen(cmdW, modeW); + + HeapFree(GetProcessHeap(), 0, cmdW); + HeapFree(GetProcessHeap(), 0, modeW); + return ret; }
/*********************************************************************