Hans Leidekker : msvcrt: Implement _wsystem and forward system to it. Respect COMSPEC environment variable.
Alexandre Julliard
julliard at winehq.org
Tue Jan 8 10:21:43 CST 2008
Module: wine
Branch: master
Commit: 3debf28215fcf5d76e034dfc17354391512500a1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3debf28215fcf5d76e034dfc17354391512500a1
Author: Hans Leidekker <hans at it.vu.nl>
Date: Mon Jan 7 14:22:23 2008 +0100
msvcrt: Implement _wsystem and forward system to it. Respect COMSPEC environment variable.
---
dlls/msvcrt/data.c | 4 +-
dlls/msvcrt/msvcrt.h | 2 +
dlls/msvcrt/msvcrt.spec | 2 +-
dlls/msvcrt/process.c | 63 +++++++++++++++++++++++++++++++++++++++++------
4 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcrt/data.c b/dlls/msvcrt/data.c
index fa53b85..578130b 100644
--- a/dlls/msvcrt/data.c
+++ b/dlls/msvcrt/data.c
@@ -229,7 +229,7 @@ char*** CDECL __p___initenv(void) { return &MSVCRT___initenv; }
MSVCRT_wchar_t*** CDECL __p___winitenv(void) { return &MSVCRT___winitenv; }
/* INTERNAL: Create a wide string from an ascii string */
-static MSVCRT_wchar_t *wstrdupa(const char *str)
+MSVCRT_wchar_t *msvcrt_wstrdupa(const char *str)
{
const size_t len = strlen(str) + 1 ;
MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t));
@@ -249,7 +249,7 @@ void msvcrt_init_args(void)
DWORD version;
MSVCRT__acmdln = _strdup( GetCommandLineA() );
- MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln);
+ MSVCRT__wcmdln = msvcrt_wstrdupa(MSVCRT__acmdln);
MSVCRT___argc = __wine_main_argc;
MSVCRT___argv = __wine_main_argv;
MSVCRT___wargv = __wine_main_wargv;
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 5d4540f..59c42cb 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -125,6 +125,8 @@ extern MSVCRT_wchar_t **_wenviron;
extern char ** msvcrt_SnapshotOfEnvironmentA(char **);
extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **);
+MSVCRT_wchar_t *msvcrt_wstrdupa(const char *);
+
/* FIXME: This should be declared in new.h but it's not an extern "C" so
* it would not be much use anyway. Even for Winelib applications.
*/
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index fffe883..b0fa5e9 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -570,7 +570,7 @@
@ cdecl _wstat64(wstr ptr) MSVCRT__wstat64
@ cdecl _wstrdate(ptr)
@ cdecl _wstrtime(ptr)
-@ stub _wsystem #(wstr)
+@ cdecl _wsystem(wstr)
@ cdecl _wtempnam(wstr wstr)
@ stub _wtmpnam #(ptr)
@ cdecl _wtoi(wstr) ntdll._wtoi
diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c
index 14f8e9a..46481ef 100644
--- a/dlls/msvcrt/process.c
+++ b/dlls/msvcrt/process.c
@@ -269,6 +269,22 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
return ret;
}
+/* INTERNAL: retrieve COMSPEC environment variable */
+static MSVCRT_wchar_t *msvcrt_get_comspec(void)
+{
+ static const MSVCRT_wchar_t cmd[] = {'c','m','d',0};
+ static const MSVCRT_wchar_t comspec[] = {'C','O','M','S','P','E','C',0};
+ MSVCRT_wchar_t *ret;
+ unsigned int len;
+
+ if (!(len = GetEnvironmentVariableW(comspec, NULL, 0))) len = sizeof(cmd)/sizeof(MSVCRT_wchar_t);
+ if ((ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t))))
+ {
+ if (!GetEnvironmentVariableW(comspec, ret, len)) strcpyW(ret, cmd);
+ }
+ return ret;
+}
+
/*********************************************************************
* _cwait (MSVCRT.@)
*/
@@ -822,19 +838,50 @@ int CDECL MSVCRT__pclose(MSVCRT_FILE* file)
}
/*********************************************************************
+ * _wsystem (MSVCRT.@)
+ *
+ * Unicode version of system
+ */
+int CDECL _wsystem(const MSVCRT_wchar_t* cmd)
+{
+ int res;
+ MSVCRT_wchar_t *comspec, *fullcmd;
+ unsigned int len;
+ static const MSVCRT_wchar_t flag[] = {' ','/','c',' ',0};
+
+ if (!(comspec = msvcrt_get_comspec())) return -1;
+ len = strlenW(comspec) + strlenW(flag) + strlenW(cmd) + 1;
+
+ if (!(fullcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t))))
+ {
+ HeapFree(GetProcessHeap(), 0, comspec);
+ return -1;
+ }
+ strcpyW(fullcmd, comspec);
+ strcatW(fullcmd, flag);
+ strcatW(fullcmd, cmd);
+
+ res = msvcrt_spawn_wide(MSVCRT__P_WAIT, comspec, fullcmd, NULL);
+
+ HeapFree(GetProcessHeap(), 0, comspec);
+ HeapFree(GetProcessHeap(), 0, fullcmd);
+ return res;
+}
+
+/*********************************************************************
* system (MSVCRT.@)
*/
int CDECL MSVCRT_system(const char* cmd)
{
- char* cmdcopy;
- int res;
+ int res = -1;
+ MSVCRT_wchar_t *cmdW;
- /* Make a writable copy for CreateProcess */
- cmdcopy=_strdup(cmd);
- /* FIXME: should probably launch cmd interpreter in COMSPEC */
- res=msvcrt_spawn(MSVCRT__P_WAIT, NULL, cmdcopy, NULL);
- MSVCRT_free(cmdcopy);
- return res;
+ if ((cmdW = msvcrt_wstrdupa(cmd)))
+ {
+ res = _wsystem(cmdW);
+ HeapFree(GetProcessHeap(), 0, cmdW);
+ }
+ return res;
}
/*********************************************************************
More information about the wine-cvs
mailing list