job.c (construct_command_argv_internal): Remove " from
authorEli Zaretskii <eliz@gnu.org>
Fri, 7 Dec 2012 14:23:39 +0000 (14:23 +0000)
committerEli Zaretskii <eliz@gnu.org>
Fri, 7 Dec 2012 14:23:39 +0000 (14:23 +0000)
 sh_chars_dos[].  Ignore an escaped backslash inside a string
 quoted with "..".  This lifts the 4KB or 8KB command-line length
 limitation imposed by the Windows shell when a command uses quoted
 strings, because we now don't call the shell in that case.

ChangeLog
job.c

index 26e0bb4af90618651d929d96f115119b04de0682..3a70bef8ab758d8aa8cbf53be511cd789334494d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2012-12-07  Eli Zaretskii  <eliz@gnu.org>
 
+       * job.c (construct_command_argv_internal): Remove " from
+       sh_chars_dos[].  Ignore an escaped backslash inside a string
+       quoted with "..".  This lifts the 4KB or 8KB command-line length
+       limitation imposed by the Windows shell when a command uses quoted
+       strings, because we now don't call the shell in that case.
+
        * job.c (create_batch_file): Declare the counter of batch files
        static, to avoid having 2 jobs using the same file name and
        stepping on each other's toes.  When all 64K names are used up,
diff --git a/job.c b/job.c
index 8e4c3a5521fae550565c33854a419aef5eb07f5b..4c87ca064597d6628ca68d5779b37363ceab7224 100644 (file)
--- a/job.c
+++ b/job.c
@@ -2491,7 +2491,14 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
                             "unset", "unsetenv", "version",
                             0 };
 #elif defined (WINDOWS32)
-  static char sh_chars_dos[] = "\"|&<>";
+  /* We used to have a double quote (") in sh_chars_dos[] below, but
+     that caused any command line with quoted file names be run
+     through a temporary batch file, which introduces command-line
+     limit of 4K charcaters imposed by cmd.exe.  Since CreateProcess
+     can handle quoted file names just fine, removing the quote lifts
+     the limit from a very frequent use case, because using quoted
+     file names is commonplace on MS-Windows.  */
+  static char sh_chars_dos[] = "|&<>";
   static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp",
                                 "chdir", "cls", "color", "copy", "ctty",
                                 "date", "del", "dir", "echo", "echo.",
@@ -2683,6 +2690,10 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
             quotes have the same effect.  */
          else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell)
            goto slow;
+#ifdef WINDOWS32
+         else if (instring == '"' && strncmp (p, "\\\"", 2) == 0)
+           *ap++ = *++p;
+#endif
          else
            *ap++ = *p;
        }