diff src/process.c @ 103095:65cc22e2c624

* fns.c (Flocale_info): Protect vector from GC during decoding. * process.c (Fstart_process): Protect argv strings from GC during encoding.
author Andreas Schwab <schwab@linux-m68k.org>
date Tue, 28 Apr 2009 19:02:26 +0000
parents 0f4ba7f17aa0
children e61fae00d13e
line wrap: on
line diff
--- a/src/process.c	Tue Apr 28 19:00:38 2009 +0000
+++ b/src/process.c	Tue Apr 28 19:02:26 2009 +0000
@@ -1698,8 +1698,6 @@
     XPROCESS (proc)->encode_coding_system = val;
   }
 
-  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
-
   /* If program file name is not absolute, search our path for it.
      Put the name we will really use in TEM.  */
   if (!IS_DIRECTORY_SEP (SREF (program, 0))
@@ -1729,26 +1727,42 @@
       && SREF (tem, 1) == ':')
     tem = Fsubstring (tem, make_number (2), Qnil);
 
-  /* Encode the file name and put it in NEW_ARGV.
-     That's where the child will use it to execute the program.  */
-  tem = ENCODE_FILE (tem);
-  new_argv[0] = SDATA (tem);
-
-  /* Here we encode arguments by the coding system used for sending
-     data to the process.  We don't support using different coding
-     systems for encoding arguments and for encoding data sent to the
-     process.  */
-
-  for (i = 3; i < nargs; i++)
+  {
+    struct gcpro gcpro1;
+    GCPRO1 (tem);
+
+    /* Encode the file name and put it in NEW_ARGV.
+       That's where the child will use it to execute the program.  */
+    tem = Fcons (ENCODE_FILE (tem), Qnil);
+
+    /* Here we encode arguments by the coding system used for sending
+       data to the process.  We don't support using different coding
+       systems for encoding arguments and for encoding data sent to the
+       process.  */
+
+    for (i = 3; i < nargs; i++)
+      {
+	tem = Fcons (args[i], tem);
+	CHECK_STRING (XCAR (tem));
+	if (STRING_MULTIBYTE (XCAR (tem)))
+	  XSETCAR (tem,
+		   code_convert_string_norecord
+		   (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
+      }
+
+    UNGCPRO;
+  }
+
+  /* Now that everything is encoded we can collect the strings into
+     NEW_ARGV.  */
+  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
+  new_argv[nargs - 2] = 0;
+
+  for (i = nargs - 3; i >= 0; i--)
     {
-      tem = args[i];
-      CHECK_STRING (tem);
-      if (STRING_MULTIBYTE (tem))
-	tem = (code_convert_string_norecord
-	       (tem, XPROCESS (proc)->encode_coding_system, 1));
-      new_argv[i - 2] = SDATA (tem);
+      new_argv[i] = SDATA (XCAR (tem));
+      tem = XCDR (tem);
     }
-  new_argv[i - 2] = 0;
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
   XPROCESS (proc)->decoding_carryover = 0;