Hans Leidekker : msvcrt: Rewrite _execl/ _spawnl functions as wrappers around wide character implementations.

Alexandre Julliard julliard at winehq.org
Tue Jan 8 10:21:44 CST 2008


Module: wine
Branch: master
Commit: 1ba54f3337df5b9d03cb939315224ae824c08886
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1ba54f3337df5b9d03cb939315224ae824c08886

Author: Hans Leidekker <hans at it.vu.nl>
Date:   Mon Jan  7 14:22:46 2008 +0100

msvcrt: Rewrite _execl/_spawnl functions as wrappers around wide character implementations.

---

 dlls/msvcrt/process.c |  188 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 121 insertions(+), 67 deletions(-)

diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c
index 2db9a7d..dc22fcb 100644
--- a/dlls/msvcrt/process.c
+++ b/dlls/msvcrt/process.c
@@ -215,16 +215,57 @@ static MSVCRT_wchar_t* msvcrt_argvtos_wide(const MSVCRT_wchar_t* const* arg, MSV
   return ret;
 }
 
-/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
- * extra '\0' to terminate it
+/* INTERNAL: Convert ansi argv list to a single 'delim'-separated wide string, with an
+ * extra '\0' to terminate it.
  */
-static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
+static MSVCRT_wchar_t *msvcrt_argvtos_aw(const char * const *arg, MSVCRT_wchar_t delim)
+{
+  const char * const *a;
+  unsigned long len;
+  MSVCRT_wchar_t *p, *ret;
+
+  if (!arg && !delim)
+  {
+      /* Return NULL for an empty environment list */
+      return NULL;
+  }
+
+  /* get length */
+  a = arg;
+  len = 0;
+  while (*a)
+  {
+    len += MultiByteToWideChar(CP_ACP, 0, *a, -1, NULL, 0);
+    a++;
+  }
+
+  ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t));
+  if (!ret)
+    return NULL;
+
+  /* fill string */
+  a = arg;
+  p = ret;
+  while (*a)
+  {
+    p += MultiByteToWideChar(CP_ACP, 0, *a, strlen(*a), p, len - (p - ret));
+    *p++ = delim;
+    a++;
+  }
+  if (delim && p > ret) p[-1] = 0;
+  else *p = 0;
+  return ret;
+}
+
+/* INTERNAL: Convert ansi va_list to a single 'delim'-separated wide string, with an
+ * extra '\0' to terminate it.
+ */
+static MSVCRT_wchar_t *msvcrt_valisttos_aw(const char *arg0, va_list alist, MSVCRT_wchar_t delim)
 {
   va_list alist2;
-  long size;
+  unsigned long len;
   const char *arg;
-  char* p;
-  char *ret;
+  MSVCRT_wchar_t *p, *ret;
 
 #ifdef HAVE_VA_COPY
   va_copy(alist2,alist);
@@ -244,13 +285,13 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
 
   /* get length */
   arg = arg0;
-  size = 0;
+  len = 0;
   do {
-      size += strlen(arg) + 1;
+      len += MultiByteToWideChar(CP_ACP, 0, arg, -1, NULL, 0);
       arg = va_arg(alist, char*);
   } while (arg != NULL);
 
-  ret = MSVCRT_malloc(size + 1);
+  ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t));
   if (!ret)
     return NULL;
 
@@ -258,9 +299,7 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
   arg = arg0;
   p = ret;
   do {
-      int len = strlen(arg);
-      memcpy(p,arg,len);
-      p += len;
+      p += MultiByteToWideChar(CP_ACP, 0, arg, strlen(arg), p, len - (p - ret));
       *p++ = delim;
       arg = va_arg(alist2, char*);
   } while (arg != NULL);
@@ -327,16 +366,19 @@ MSVCRT_intptr_t CDECL _cwait(int *status, MSVCRT_intptr_t pid, int action)
 MSVCRT_intptr_t CDECL _execl(const char* name, const char* arg0, ...)
 {
   va_list ap;
-  char * args;
-  MSVCRT_intptr_t ret;
+  MSVCRT_wchar_t *nameW, *args;
+  MSVCRT_intptr_t ret = -1;
+
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
 
   va_start(ap, arg0);
-  args = msvcrt_valisttos(arg0, ap, ' ');
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
   va_end(ap);
 
-  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, NULL);
-  MSVCRT_free(args);
+  ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, nameW, args, NULL);
 
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
   return ret;
 }
 
@@ -357,20 +399,22 @@ MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...)
  */
 MSVCRT_intptr_t CDECL _execlp(const char* name, const char* arg0, ...)
 {
+  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
   va_list ap;
-  char * args;
+  MSVCRT_wchar_t *nameW, *args, fullname[MAX_PATH];
   MSVCRT_intptr_t ret;
-  char fullname[MAX_PATH];
 
-  _searchenv(name, "PATH", fullname);
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
+  _wsearchenv(nameW, path, fullname);
 
   va_start(ap, arg0);
-  args = msvcrt_valisttos(arg0, ap, ' ');
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
   va_end(ap);
 
-  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, NULL);
-  MSVCRT_free(args);
+  ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, fullname[0] ? fullname : nameW, args, NULL);
 
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
   return ret;
 }
 
@@ -440,16 +484,19 @@ MSVCRT_intptr_t CDECL _execvp(const char* name, char* const* argv)
 MSVCRT_intptr_t CDECL _spawnl(int flags, const char* name, const char* arg0, ...)
 {
   va_list ap;
-  char * args;
+  MSVCRT_wchar_t *nameW, *args;
   MSVCRT_intptr_t ret;
 
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
+
   va_start(ap, arg0);
-  args = msvcrt_valisttos(arg0, ap, ' ');
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
   va_end(ap);
 
-  ret = msvcrt_spawn(flags, name, args, NULL);
-  MSVCRT_free(args);
+  ret = msvcrt_spawn_wide(flags, nameW, args, NULL);
 
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
   return ret;
 }
 
@@ -458,26 +505,29 @@ MSVCRT_intptr_t CDECL _spawnl(int flags, const char* name, const char* arg0, ...
  */
 MSVCRT_intptr_t CDECL _spawnle(int flags, const char* name, const char* arg0, ...)
 {
-    va_list ap;
-    char *args, *envs = NULL;
-    const char * const *envp;
-    MSVCRT_intptr_t ret;
+  va_list ap;
+  MSVCRT_wchar_t *nameW, *args, *envs = NULL;
+  const char * const *envp;
+  MSVCRT_intptr_t ret;
 
-    va_start(ap, arg0);
-    args = msvcrt_valisttos(arg0, ap, ' ');
-    va_end(ap);
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
 
-    va_start(ap, arg0);
-    while (va_arg( ap, char * ) != NULL) /*nothing*/;
-    envp = va_arg( ap, const char * const * );
-    if (envp) envs = msvcrt_argvtos(envp, 0);
-    va_end(ap);
+  va_start(ap, arg0);
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
+  va_end(ap);
 
-    ret = msvcrt_spawn(flags, name, args, envs);
+  va_start(ap, arg0);
+  while (va_arg( ap, char * ) != NULL) /*nothing*/;
+  envp = va_arg( ap, const char * const * );
+  if (envp) envs = msvcrt_argvtos_aw(envp, 0);
+  va_end(ap);
 
-    MSVCRT_free(args);
-    MSVCRT_free(envs);
-    return ret;
+  ret = msvcrt_spawn_wide(flags, nameW, args, envs);
+
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
+  MSVCRT_free(envs);
+  return ret;
 }
 
 
@@ -489,20 +539,22 @@ MSVCRT_intptr_t CDECL _spawnle(int flags, const char* name, const char* arg0, ..
  */
 MSVCRT_intptr_t CDECL _spawnlp(int flags, const char* name, const char* arg0, ...)
 {
+  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
   va_list ap;
-  char * args;
+  MSVCRT_wchar_t *nameW, *args, fullname[MAX_PATH];
   MSVCRT_intptr_t ret;
-  char fullname[MAX_PATH];
 
-  _searchenv(name, "PATH", fullname);
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
+  _wsearchenv(nameW, path, fullname);
 
   va_start(ap, arg0);
-  args = msvcrt_valisttos(arg0, ap, ' ');
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
   va_end(ap);
 
-  ret = msvcrt_spawn(flags, fullname[0] ? fullname : name, args, NULL);
-  MSVCRT_free(args);
+  ret = msvcrt_spawn_wide(flags, fullname[0] ? fullname : nameW, args, NULL);
 
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
   return ret;
 }
 
@@ -511,29 +563,31 @@ MSVCRT_intptr_t CDECL _spawnlp(int flags, const char* name, const char* arg0, ..
  */
 MSVCRT_intptr_t CDECL _spawnlpe(int flags, const char* name, const char* arg0, ...)
 {
-    va_list ap;
-    char *args, *envs = NULL;
-    const char * const *envp;
-    MSVCRT_intptr_t ret;
-    char fullname[MAX_PATH];
+  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
+  va_list ap;
+  MSVCRT_wchar_t *nameW, *args, *envs = NULL, fullname[MAX_PATH];
+  const char * const *envp;
+  MSVCRT_intptr_t ret;
 
-    _searchenv(name, "PATH", fullname);
+  if (!(nameW = msvcrt_wstrdupa(name))) return -1;
+  _wsearchenv(nameW, path, fullname);
 
-    va_start(ap, arg0);
-    args = msvcrt_valisttos(arg0, ap, ' ');
-    va_end(ap);
+  va_start(ap, arg0);
+  args = msvcrt_valisttos_aw(arg0, ap, ' ');
+  va_end(ap);
 
-    va_start(ap, arg0);
-    while (va_arg( ap, char * ) != NULL) /*nothing*/;
-    envp = va_arg( ap, const char * const * );
-    if (envp) envs = msvcrt_argvtos(envp, 0);
-    va_end(ap);
+  va_start(ap, arg0);
+  while (va_arg( ap, char * ) != NULL) /*nothing*/;
+  envp = va_arg( ap, const char * const * );
+  if (envp) envs = msvcrt_argvtos_aw(envp, 0);
+  va_end(ap);
 
-    ret = msvcrt_spawn(flags, fullname[0] ? fullname : name, args, envs);
+  ret = msvcrt_spawn_wide(flags, fullname[0] ? fullname : nameW, args, envs);
 
-    MSVCRT_free(args);
-    MSVCRT_free(envs);
-    return ret;
+  MSVCRT_free(nameW);
+  MSVCRT_free(args);
+  MSVCRT_free(envs);
+  return ret;
 }
 
 /*********************************************************************




More information about the wine-cvs mailing list