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