msvcrt_valisttos optimization (cmdline3)

Francois Gouget fgouget at free.fr
Fri Sep 7 22:41:49 CDT 2001


   This is an update of this patch which changes the way system is
implemented. CreateProcess may modify the command line it is passed in
parameter. Thus system should copy the command line before giving it to
CreateProcess.
   Also this makes p20010902-cmdline4.diff unnecessary (at least until
we find an application that gives a read-only command line to
CreateProcess).


Changelog:

 * dlls/msvcrt/process.c
   Rewrite msvcrt_{argvtos,valisttos} to be more efficient
   Warn about the ' ' and '"' handling of the exec and spawn functions
   Copy the command line in MSVCRT_system to make it writable


 
--
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
  Good judgment comes from experience, and experience comes from bad judgment
                               -- Barry LePatner

-------------- next part --------------
Index: include/msvcrt/process.h
===================================================================
RCS file: /home/wine/wine/include/msvcrt/process.h,v
retrieving revision 1.2
diff -u -r1.2 process.h
--- include/msvcrt/process.h	2001/06/19 03:46:27	1.2
+++ include/msvcrt/process.h	2001/09/08 01:38:00
@@ -55,7 +55,7 @@
 int         _spawnlpe(int,const char*,const char*,...);
 int         _spawnv(int,const char*,const char* const *);
 int         _spawnve(int,const char*,const char* const *,const char* const *);
-int         _spawnvp(int,const char* ,const char* const *);
+int         _spawnvp(int,const char*,const char* const *);
 int         _spawnvpe(int,const char*,const char* const *,const char* const *);
 
 void        MSVCRT(_c_exit)(void);
Index: dlls/msvcrt/process.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/process.c,v
retrieving revision 1.7
diff -u -r1.7 process.c
--- dlls/msvcrt/process.c	2001/05/22 19:18:51	1.7
+++ dlls/msvcrt/process.c	2001/09/08 01:37:53
@@ -16,6 +16,7 @@
 
 #include "msvcrt/process.h"
 #include "msvcrt/stdlib.h"
+#include "msvcrt/string.h"
 
 DEFAULT_DEBUG_CHANNEL(msvcrt);
 
@@ -26,7 +27,7 @@
 static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm';
 
 /* INTERNAL: Spawn a child process */
-static int msvcrt_spawn(int flags, const char* exe, char* args, char* env)
+static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
 {
   STARTUPINFOA si;
   PROCESS_INFORMATION pi;
@@ -45,7 +46,7 @@
   memset(&si, 0, sizeof(si));
   si.cb = sizeof(si);
 
-  if (!CreateProcessA(exe, args, NULL, NULL, TRUE,
+  if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
                      flags == _P_DETACH ? DETACHED_PROCESS : 0,
                      env, NULL, &si, &pi))
   {
@@ -75,76 +76,90 @@
   return -1; /* can't reach here */
 }
 
-/* INTERNAL: Convert argv list to a single 'delim'-separated string */
+/* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
+ * extra '\0' to terminate it
+ */
 static char* msvcrt_argvtos(const char* const* arg, char delim)
 {
-  const char* const* search = arg;
-  long size = 0;
-  char *ret;
+  const char* const* a;
+  long size;
+  char* p;
+  char* ret;
 
   if (!arg && !delim)
-    return NULL;
+  {
+      /* Return NULL for an empty environment list */
+      return NULL;
+  }
 
   /* get length */
-  while(*search)
+  a = arg;
+  size = 0;
+  while (*a)
   {
-    size += strlen(*search) + 1;
-    search++;
+    size += strlen(*a) + 1;
+    a++;
   }
 
-  if (!(ret = (char *)MSVCRT_calloc(size + 1, 1)))
+  ret = (char*)MSVCRT_malloc(size + 1);
+  if (!ret)
     return NULL;
 
   /* fill string */
-  search = arg;
-  size = 0;
-  while(*search)
+  a = arg;
+  p = ret;
+  while (*a)
   {
-    int strsize = strlen(*search);
-    memcpy(ret+size,*search,strsize);
-    ret[size+strsize] = delim;
-    size += strsize + 1;
-    search++;
+    int len = strlen(*a);
+    memcpy(ret+size,*a,len);
+    p += len;
+    *p++ = delim;
+    a++;
   }
+  *p='\0';
   return ret;
 }
 
-/* INTERNAL: Convert va_list to a single 'delim'-separated string */
-static char* msvcrt_valisttos(const char* arg0, va_list ap, char delim)
+/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
+ * extra '\0' to terminate it
+ */
+static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
 {
-  va_list search = ap;
+  va_list alist2 = alist;
   long size;
-  char *arg;
+  const char *arg;
+  char* p;
   char *ret;
-  int strsize;
 
   if (!arg0 && !delim)
-    return NULL;
-
-  /* get length */
-  size = strlen(arg0) + 1;
-  while((arg = va_arg(search, char *)) != NULL)
   {
-    size += strlen(arg) + 1;
+      /* Return NULL for an empty environment list */
+      return NULL;
   }
+
+  /* get length */
+  arg = arg0;
+  size = 0;
+  do {
+      size += strlen(arg) + 1;
+      arg = va_arg(alist, char*);
+  } while (arg != NULL);
 
-  if (!(ret = (char *)MSVCRT_calloc(size + 1, 1)))
+  ret = (char*)MSVCRT_malloc(size + 1);
+  if (!ret)
     return NULL;
 
   /* fill string */
-  search = ap;
-  size = 0;
-  strsize = strlen(arg0);
-  memcpy(ret+size,arg0,strsize);
-  ret[size+strsize] = delim;
-  size += strsize + 1;
-  while((arg = va_arg(search, char *)) != NULL)
-  {
-    strsize = strlen(search);
-    memcpy(ret+size,search,strsize);
-    ret[size+strsize] = delim;
-    size += strsize + 1;
-  }
+  arg = arg0;
+  p = ret;
+  do {
+      int len = strlen(arg);
+      memcpy(p,arg,len);
+      p += len;
+      *p++ = delim;
+      arg = va_arg(alist2, char*);
+  } while (arg != NULL);
+  *p = '\0';
   return ret;
 }
 
@@ -183,6 +198,9 @@
 
 /*********************************************************************
  *		_execl (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execl(const char* name, const char* arg0, ...)
 {
@@ -202,6 +220,9 @@
 
 /*********************************************************************
  *		_execlp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execlp(const char* name, const char* arg0, ...)
 {
@@ -224,6 +245,9 @@
 
 /*********************************************************************
  *		_execv (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execv(const char* name, char* const* argv)
 {
@@ -232,6 +256,9 @@
 
 /*********************************************************************
  *		_execve (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execve(const char* name, char* const* argv, const char* const* envv)
 {
@@ -240,6 +267,9 @@
 
 /*********************************************************************
  *		_execvpe (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execvpe(const char* name, char* const* argv, const char* const* envv)
 {
@@ -252,6 +282,9 @@
 
 /*********************************************************************
  *		_execvp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _execvp(const char* name, char* const* argv)
 {
@@ -260,6 +293,9 @@
 
 /*********************************************************************
  *		_spawnl (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnl(int flags, const char* name, const char* arg0, ...)
 {
@@ -279,6 +315,9 @@
 
 /*********************************************************************
  *		_spawnlp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnlp(int flags, const char* name, const char* arg0, ...)
 {
@@ -301,6 +340,9 @@
 
 /*********************************************************************
  *		_spawnve (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnve(int flags, const char* name, const char* const* argv,
                             const char* const* envv)
@@ -326,6 +368,9 @@
 
 /*********************************************************************
  *		_spawnv (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnv(int flags, const char* name, const char* const* argv)
 {
@@ -334,6 +379,9 @@
 
 /*********************************************************************
  *		_spawnvpe (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnvpe(int flags, const char* name, const char* const* argv,
                             const char* const* envv)
@@ -345,6 +393,9 @@
 
 /*********************************************************************
  *		_spawnvp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces 
+ * or double-quotes.
  */
 int _spawnvp(int flags, const char* name, const char* const* argv)
 {
@@ -356,8 +407,15 @@
  */
 int MSVCRT_system(const char* cmd)
 {
-  /* FIXME: should probably launch cmd interpreter in COMSPEC */
-  return msvcrt_spawn(_P_WAIT, cmd, NULL, NULL);
+    char* cmdcopy;
+    int res;
+
+    /* Make a writable copy for CreateProcess */
+    cmdcopy=_strdup(cmd);
+    /* FIXME: should probably launch cmd interpreter in COMSPEC */
+    res=msvcrt_spawn(_P_WAIT, NULL, cmdcopy, NULL);
+    MSVCRT_free(cmdcopy);
+    return res;
 }
 
 /*********************************************************************


More information about the wine-patches mailing list