Hans Leidekker : msvcrt: Implement _wexecl{, e, p, pe}.

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


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

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

msvcrt: Implement _wexecl{, e, p, pe}.

---

 dlls/msvcrt/msvcrt.spec |    8 +-
 dlls/msvcrt/process.c   |  162 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index b0fa5e9..cff8ecd 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -518,10 +518,10 @@
 @ cdecl _wcsupr(wstr) ntdll._wcsupr
 @ cdecl _wctime(ptr) MSVCRT__wctime
 @ extern _wenviron
-@ stub _wexecl #(wstr wstr) varargs
-@ stub _wexecle #(wstr wstr) varargs
-@ stub _wexeclp #(wstr wstr) varargs
-@ stub _wexeclpe #(wstr wstr) varargs
+@ varargs _wexecl(wstr wstr)
+@ varargs _wexecle(wstr wstr)
+@ varargs _wexeclp(wstr wstr)
+@ varargs _wexeclpe(wstr wstr)
 @ stub _wexecv #(wstr ptr)
 @ stub _wexecve #(wstr ptr ptr)
 @ stub _wexecvp #(wstr ptr)
diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c
index 7835d88..fa8f52a 100644
--- a/dlls/msvcrt/process.c
+++ b/dlls/msvcrt/process.c
@@ -81,6 +81,9 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const MSVCRT_wchar_t* exe, MSVCRT
   return -1; /* can't reach here */
 }
 
+/* INTERNAL: Convert wide argv list to a single 'delim'-separated wide string, with an
+ * extra '\0' to terminate it.
+ */
 static MSVCRT_wchar_t* msvcrt_argvtos(const MSVCRT_wchar_t* const* arg, MSVCRT_wchar_t delim)
 {
   const MSVCRT_wchar_t* const* a;
@@ -165,6 +168,59 @@ static MSVCRT_wchar_t *msvcrt_argvtos_aw(const char * const *arg, MSVCRT_wchar_t
   return ret;
 }
 
+/* INTERNAL: Convert wide va_list to a single 'delim'-separated wide string, with an
+ * extra '\0' to terminate it.
+ */
+static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alist, MSVCRT_wchar_t delim)
+{
+  va_list alist2;
+  unsigned long len;
+  const MSVCRT_wchar_t *arg;
+  MSVCRT_wchar_t *p, *ret;
+
+#ifdef HAVE_VA_COPY
+  va_copy(alist2,alist);
+#else
+# ifdef HAVE___VA_COPY
+  __va_copy(alist2,alist);
+# else
+  alist2 = alist;
+# endif
+#endif
+
+  if (!arg0)
+  {
+      /* Return NULL for an empty environment list */
+      return NULL;
+  }
+
+  /* get length */
+  arg = arg0;
+  len = 0;
+  do {
+      len += strlenW(arg) + 1;
+      arg = va_arg(alist, MSVCRT_wchar_t*);
+  } while (arg != NULL);
+
+  ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t));
+  if (!ret)
+    return NULL;
+
+  /* fill string */
+  arg = arg0;
+  p = ret;
+  do {
+      len = strlenW(arg);
+      memcpy(p, arg, len * sizeof(MSVCRT_wchar_t));
+      p += len;
+      *p++ = delim;
+      arg = va_arg(alist2, MSVCRT_wchar_t*);
+  } while (arg != NULL);
+  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.
  */
@@ -266,6 +322,27 @@ MSVCRT_intptr_t CDECL _cwait(int *status, MSVCRT_intptr_t pid, int action)
 }
 
 /*********************************************************************
+ *      _wexecl (MSVCRT.@)
+ *
+ * Unicode version of _execl
+ */
+MSVCRT_intptr_t CDECL _wexecl(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...)
+{
+  va_list ap;
+  MSVCRT_wchar_t *args;
+  MSVCRT_intptr_t ret;
+
+  va_start(ap, arg0);
+  args = msvcrt_valisttos(arg0, ap, ' ');
+  va_end(ap);
+
+  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, NULL);
+
+  MSVCRT_free(args);
+  return ret;
+}
+
+/*********************************************************************
  *		_execl (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -291,6 +368,35 @@ MSVCRT_intptr_t CDECL _execl(const char* name, const char* arg0, ...)
 }
 
 /*********************************************************************
+ *      _wexecle (MSVCRT.@)
+ *
+ * Unicode version of _execle
+ */
+MSVCRT_intptr_t CDECL _wexecle(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...)
+{
+  va_list ap;
+  MSVCRT_wchar_t *args, *envs = NULL;
+  const MSVCRT_wchar_t * const *envp;
+  MSVCRT_intptr_t ret;
+
+  va_start(ap, arg0);
+  args = msvcrt_valisttos(arg0, ap, ' ');
+  va_end(ap);
+
+  va_start(ap, arg0);
+  while (va_arg( ap, MSVCRT_wchar_t * ) != NULL) /*nothing*/;
+  envp = va_arg( ap, const MSVCRT_wchar_t * const * );
+  if (envp) envs = msvcrt_argvtos(envp, 0);
+  va_end(ap);
+
+  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, envs);
+
+  MSVCRT_free(args);
+  MSVCRT_free(envs);
+  return ret;
+}
+
+/*********************************************************************
  *		_execle (MSVCRT.@)
  */
 MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...)
@@ -321,6 +427,30 @@ MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...)
 }
 
 /*********************************************************************
+ *      _wexeclp (MSVCRT.@)
+ *
+ * Unicode version of _execlp
+ */
+MSVCRT_intptr_t CDECL _wexeclp(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...)
+{
+  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
+  va_list ap;
+  MSVCRT_wchar_t *args, fullname[MAX_PATH];
+  MSVCRT_intptr_t ret;
+
+  _wsearchenv(name, path, fullname);
+
+  va_start(ap, arg0);
+  args = msvcrt_valisttos(arg0, ap, ' ');
+  va_end(ap);
+
+  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, NULL);
+
+  MSVCRT_free(args);
+  return ret;
+}
+
+/*********************************************************************
  *		_execlp (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -348,6 +478,38 @@ MSVCRT_intptr_t CDECL _execlp(const char* name, const char* arg0, ...)
 }
 
 /*********************************************************************
+ *      _wexeclpe (MSVCRT.@)
+ *
+ * Unicode version of _execlpe
+ */
+MSVCRT_intptr_t CDECL _wexeclpe(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...)
+{
+  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
+  va_list ap;
+  MSVCRT_wchar_t *args, *envs = NULL, fullname[MAX_PATH];
+  const MSVCRT_wchar_t * const *envp;
+  MSVCRT_intptr_t ret;
+
+  _wsearchenv(name, path, fullname);
+
+  va_start(ap, arg0);
+  args = msvcrt_valisttos(arg0, ap, ' ');
+  va_end(ap);
+
+  va_start(ap, arg0);
+  while (va_arg( ap, MSVCRT_wchar_t * ) != NULL) /*nothing*/;
+  envp = va_arg( ap, const MSVCRT_wchar_t * const * );
+  if (envp) envs = msvcrt_argvtos(envp, 0);
+  va_end(ap);
+
+  ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, envs);
+
+  MSVCRT_free(args);
+  MSVCRT_free(envs);
+  return ret;
+}
+
+/*********************************************************************
  *		_execlpe (MSVCRT.@)
  */
 MSVCRT_intptr_t CDECL _execlpe(const char* name, const char* arg0, ...)




More information about the wine-cvs mailing list