changeset 29675:2f6f53651d29

unistd-wrappers.c: Use prepare_spawn from upstream gnulib (bug #60535). * liboctave/wrappers/unistd-wrappers.c (prepare_spawn): Remove function. (octave_execv_wrapper): Use upstream "prepare_spawn". * bootstrap.conf: Add module "windows-spawn" to list.
author Markus Mützel <markus.muetzel@gmx.de>
date Thu, 06 May 2021 13:00:03 +0200
parents fc8d0a32d840
children 08104b0629d5
files bootstrap.conf liboctave/wrappers/unistd-wrappers.c
diffstat 2 files changed, 9 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/bootstrap.conf	Fri May 14 18:31:34 2021 -0700
+++ b/bootstrap.conf	Thu May 06 13:00:03 2021 +0200
@@ -130,6 +130,7 @@
   unsetenv
   vasprintf
   waitpid
+  windows-spawn
 "
 
 # Additional gnulib files and scripts used by Octave's buildsystem.
--- a/liboctave/wrappers/unistd-wrappers.c	Fri May 14 18:31:34 2021 -0700
+++ b/liboctave/wrappers/unistd-wrappers.c	Thu May 06 13:00:03 2021 +0200
@@ -46,6 +46,10 @@
 #  include <wchar.h>
 #endif
 
+#if defined (__WIN32__) && ! defined (__CYGWIN__)
+#  include "windows-spawn.h"
+#endif
+
 #include "uniconv-wrappers.h"
 #include "unistd-wrappers.h"
 
@@ -114,143 +118,13 @@
   return dup2 (fd1, fd2);
 }
 
-#if defined (__WIN32__) && ! defined (__CYGWIN__)
-
-// Adapted from libtool wrapper.
-
-/* Prepares an argument vector before calling spawn().
-
-   Note that spawn() does not by itself call the command interpreter
-     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
-      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-         GetVersionEx(&v);
-         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
-      }) ? "cmd.exe" : "command.com").
-
-   Instead it simply concatenates the arguments, separated by ' ', and calls
-   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
-   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
-   special way:
-
-   - Space and tab are interpreted as delimiters. They are not treated as
-     delimiters if they are surrounded by double quotes: "...".
-
-   - Unescaped double quotes are removed from the input. Their only effect is
-     that within double quotes, space and tab are treated like normal
-     characters.
-
-   - Backslashes not followed by double quotes are not special.
-
-   - But 2*n+1 backslashes followed by a double quote become
-     n backslashes followed by a double quote (n >= 0):
-       \" -> "
-       \\\" -> \"
-       \\\\\" -> \\"
- */
-
-#define SHELL_SPECIAL_CHARS \
-  "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
-
-#define SHELL_SPACE_CHARS \
-  " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
-
-static char **
-prepare_spawn (char *const *argv)
-{
-  size_t argc;
-  char **new_argv;
-  size_t i;
-
-  /* Count number of arguments.  */
-  for (argc = 0; argv[argc] != NULL; argc++)
-    ;
-
-  /* Allocate new argument vector.  */
-  new_argv = (char **) malloc ((argc + 1) * sizeof (char *));
-
-  /* Put quoted arguments into the new argument vector.  */
-  for (i = 0; i < argc; i++)
-    {
-      const char *string = argv[i];
-
-      if (string[0] == '\0')
-        new_argv[i] = strdup ("\"\"");
-      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
-        {
-          int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
-          size_t length;
-          unsigned int backslashes;
-          const char *s;
-          char *quoted_string;
-          char *p;
-
-          length = 0;
-          backslashes = 0;
-          if (quote_around)
-            length++;
-          for (s = string; *s != '\0'; s++)
-            {
-              char c = *s;
-              if (c == '"')
-                length += backslashes + 1;
-              length++;
-              if (c == '\\')
-                backslashes++;
-              else
-                backslashes = 0;
-            }
-          if (quote_around)
-            length += backslashes + 1;
-
-          quoted_string = (char *) malloc (length + 1);
-
-          p = quoted_string;
-          backslashes = 0;
-          if (quote_around)
-            *p++ = '"';
-          for (s = string; *s != '\0'; s++)
-            {
-              char c = *s;
-              if (c == '"')
-                {
-                  unsigned int j;
-                  for (j = backslashes + 1; j > 0; j--)
-                    *p++ = '\\';
-                }
-              *p++ = c;
-              if (c == '\\')
-                backslashes++;
-              else
-                backslashes = 0;
-            }
-          if (quote_around)
-            {
-              unsigned int j;
-              for (j = backslashes; j > 0; j--)
-                *p++ = '\\';
-              *p++ = '"';
-            }
-          *p = '\0';
-
-          new_argv[i] = quoted_string;
-        }
-      else
-        new_argv[i] = strdup (string);
-    }
-
-  new_argv[argc] = NULL;
-
-  return new_argv;
-}
-
-#endif
-
 int
 octave_execv_wrapper (const char *file, char *const *argv)
 {
 #if defined (__WIN32__) && ! defined (__CYGWIN__)
 
-  char **sanitized_argv = prepare_spawn (argv);
+  char *argv_mem_to_free;
+  char **sanitized_argv = prepare_spawn (argv, &argv_mem_to_free);
 
 #  if defined (OCTAVE_USE_WINDOWS_API) && defined (_UNICODE)
 
@@ -268,10 +142,8 @@
 
   wargv[argc] = NULL;
 
-  char **p = sanitized_argv;
-  while (*p)
-    free (*p++);
   free (sanitized_argv);
+  free (argv_mem_to_free);
 
   int status = _wspawnv (P_OVERLAY, wfile, wargv);
 
@@ -290,10 +162,8 @@
 
   // This only happens if spawnv fails.
 
-  char **p = sanitized_argv;
-  while (*p)
-    free (*p++);
   free (sanitized_argv);
+  free (argv_mem_to_free);
 
 #  endif