The execute, spawn-pipe, etc. functions so far take a 'char **' for
an array of strings to pass as arguments to a subprocess. This is
suboptimal, because it requires casts from 'const char *' to 'char *'
in many places.

It is better to make clear through the types that the arguments strings
are not being written to. This removes the need to cast from 'const char *'
to 'char *'. It introduces the need to cast from 'const char **' to 'char **',
but in much fewer places. Since a cast from 'const char **' to 'char **'
does not violate strict aliasing rules (ISO C 11 ยง 6.5.(7)), this is OK.

IMO POSIX doesn't get this right in the functions execv(), posix_spawn(),
iconv() etc.


2020-12-11  Bruno Haible  <br...@clisp.org>

        sh-quote, execute, spawn-pipe, etc.: Make better use of 'const'.
        * lib/sh-quote.h (shell_quote_argv): Does not need write access to the
        elements of argv.
        * lib/sh-quote.c (shell_quote_argv): Likewise.
        * lib/windows-spawn.h (prepare_spawn): Add 'const' the argument type and
        the return type.
        * lib/windows-spawn.c (prepare_spawn): Likewise.
        * lib/os2-spawn.h (prepare_spawn): Likewise.
        * lib/os2-spawn.c (prepare_spawn): Likewise.
        * lib/execute.h (execute): Does not need write access to the elements of
        prog_argv.
        * lib/execute.c (execute): Likewise.
        * lib/spawn-pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi):
        Likewise.
        * lib/spawn-pipe.c (create_pipe, create_pipe_bidi, create_pipe_in,
        create_pipe_out): Likewise.
        * lib/pipe-filter.h (pipe_filter_ii_execute, pipe_filter_gi_create):
        Likewise.
        * lib/pipe-filter-ii.c (pipe_filter_ii_execute): Likewise.
        * lib/pipe-filter-gi.c (pipe_filter_gi_create): Likewise.
        * lib/javaexec.h (execute_fn): Does not need write access to the
        elements of prog_argv.
        * lib/javaexec.c (execute_java_class): Update variable types and remove
        casts to 'char *'.
        * lib/csharpexec.h (execute_fn): Does not need write access to the
        elements of prog_argv.
        * lib/csharpexec.c (execute_csharp_using_mono,
        execute_csharp_using_sscli): Update variable types and remove casts to
        'char *'.
        * lib/javacomp.c (compile_using_envjavac, compile_using_gcj,
        compile_using_javac, compile_using_jikes, is_envjavac_gcj,
        is_envjavac_gcj43, is_gcj_present, is_gcj_43, is_javac_present,
        is_jikes_present): Update variable types and remove casts to 'char *'.
        * lib/javaversion.c (execute_and_read_line): Does not need write access
        to the elements of prog_argv.
        * lib/csharpcomp.c (compile_csharp_using_mono,
        compile_csharp_using_sscli): Update variable types and remove casts to
        'char *'.
        * tests/test-sh-quote.c (main): Update variable types and remove casts
        to 'char *'.
        * tests/test-execute-main.c (main): Update variable types and remove
        casts to 'char *'.
        * tests/test-spawn-pipe-main.c (test_pipe): Update variable types and
        remove casts to 'char *'.
        * NEWS: Mention the changes.

diff --git a/NEWS b/NEWS
index 747165a..f484881 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,39 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2020-12-11  sh-quote        The argv argument of the 'shell_quote_argv' 
function
+                            is now of type 'const char * const *'.  You no
+                            longer need to cast read-only strings to 'char *'
+                            when constructing this argument.
+            execute         The prog_argv argument of the 'execute' function
+                            is now of type 'const char * const *'.  You no
+                            longer need to cast read-only strings to 'char *'
+                            when constructing this argument.
+            spawn-pipe      The prog_argv argument of the functions
+                            'create_pipe_out', 'create_pipe_in',
+                            'create_pipe_bidi' is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing 
this
+                            argument.
+            pipe-filter-gi  The prog_argv argument of the
+                            'pipe_filter_gi_create' function is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing 
this
+                            argument.
+            pipe-filter-ii  The prog_argv argument of the
+                            'pipe_filter_ii_execute' function is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing 
this
+                            argument.
+            javaexec        The prog_argv argument of the 'execute_fn' function
+                            type is now of type 'const char * const *'.  Update
+                            the signature of all your implementations of this
+                            type.
+            csharpexec      The prog_argv argument of the 'execute_fn' function
+                            type is now of type 'const char * const *'.  Update
+                            the signature of all your implementations of this
+                            type.
+
 2020-12-02  spawn-pipe      The functions 'create_pipe_out', 'create_pipe_in',
                             'create_pipe_bidi' now take a 4th argument
                             'const char *directory'. To maintain the previous
>From c893594d0c33139efbc8d75e43eaed487116b58b Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sat, 12 Dec 2020 04:18:54 +0100
Subject: [PATCH] sh-quote, execute, spawn-pipe, etc.: Make better use of
 'const'.

* lib/sh-quote.h (shell_quote_argv): Does not need write access to the
elements of argv.
* lib/sh-quote.c (shell_quote_argv): Likewise.
* lib/windows-spawn.h (prepare_spawn): Add 'const' the argument type and
the return type.
* lib/windows-spawn.c (prepare_spawn): Likewise.
* lib/os2-spawn.h (prepare_spawn): Likewise.
* lib/os2-spawn.c (prepare_spawn): Likewise.
* lib/execute.h (execute): Does not need write access to the elements of
prog_argv.
* lib/execute.c (execute): Likewise.
* lib/spawn-pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi):
Likewise.
* lib/spawn-pipe.c (create_pipe, create_pipe_bidi, create_pipe_in,
create_pipe_out): Likewise.
* lib/pipe-filter.h (pipe_filter_ii_execute, pipe_filter_gi_create):
Likewise.
* lib/pipe-filter-ii.c (pipe_filter_ii_execute): Likewise.
* lib/pipe-filter-gi.c (pipe_filter_gi_create): Likewise.
* lib/javaexec.h (execute_fn): Does not need write access to the
elements of prog_argv.
* lib/javaexec.c (execute_java_class): Update variable types and remove
casts to 'char *'.
* lib/csharpexec.h (execute_fn): Does not need write access to the
elements of prog_argv.
* lib/csharpexec.c (execute_csharp_using_mono,
execute_csharp_using_sscli): Update variable types and remove casts to
'char *'.
* lib/javacomp.c (compile_using_envjavac, compile_using_gcj,
compile_using_javac, compile_using_jikes, is_envjavac_gcj,
is_envjavac_gcj43, is_gcj_present, is_gcj_43, is_javac_present,
is_jikes_present): Update variable types and remove casts to 'char *'.
* lib/javaversion.c (execute_and_read_line): Does not need write access
to the elements of prog_argv.
* lib/csharpcomp.c (compile_csharp_using_mono,
compile_csharp_using_sscli): Update variable types and remove casts to
'char *'.
* tests/test-sh-quote.c (main): Update variable types and remove casts
to 'char *'.
* tests/test-execute-main.c (main): Update variable types and remove
casts to 'char *'.
* tests/test-spawn-pipe-main.c (test_pipe): Update variable types and
remove casts to 'char *'.
* NEWS: Mention the changes.
---
 ChangeLog                    | 48 ++++++++++++++++++++++++++++++++
 NEWS                         | 33 ++++++++++++++++++++++
 lib/csharpcomp.c             | 31 ++++++++++-----------
 lib/csharpexec.c             | 18 ++++++------
 lib/csharpexec.h             |  2 +-
 lib/execute.c                | 32 ++++++++++-----------
 lib/execute.h                |  2 +-
 lib/javacomp.c               | 48 ++++++++++++++++----------------
 lib/javaexec.c               | 43 ++++++++++++++++-------------
 lib/javaexec.h               |  2 +-
 lib/javaversion.c            |  2 +-
 lib/os2-spawn.c              |  8 +++---
 lib/os2-spawn.h              |  3 +-
 lib/pipe-filter-gi.c         |  4 +--
 lib/pipe-filter-ii.c         |  4 +--
 lib/pipe-filter.h            |  6 ++--
 lib/sh-quote.c               |  4 +--
 lib/sh-quote.h               |  2 +-
 lib/spawn-pipe.c             | 45 +++++++++++++++---------------
 lib/spawn-pipe.h             |  9 ++++--
 lib/windows-spawn.c          |  8 +++---
 lib/windows-spawn.h          |  3 +-
 tests/test-execute-main.c    | 66 ++++++++++++++++++++++----------------------
 tests/test-sh-quote.c        | 12 ++++----
 tests/test-spawn-pipe-main.c |  6 ++--
 25 files changed, 268 insertions(+), 173 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 764f554..86a1a12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,53 @@
 2020-12-11  Bruno Haible  <br...@clisp.org>
 
+	sh-quote, execute, spawn-pipe, etc.: Make better use of 'const'.
+	* lib/sh-quote.h (shell_quote_argv): Does not need write access to the
+	elements of argv.
+	* lib/sh-quote.c (shell_quote_argv): Likewise.
+	* lib/windows-spawn.h (prepare_spawn): Add 'const' the argument type and
+	the return type.
+	* lib/windows-spawn.c (prepare_spawn): Likewise.
+	* lib/os2-spawn.h (prepare_spawn): Likewise.
+	* lib/os2-spawn.c (prepare_spawn): Likewise.
+	* lib/execute.h (execute): Does not need write access to the elements of
+	prog_argv.
+	* lib/execute.c (execute): Likewise.
+	* lib/spawn-pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi):
+	Likewise.
+	* lib/spawn-pipe.c (create_pipe, create_pipe_bidi, create_pipe_in,
+	create_pipe_out): Likewise.
+	* lib/pipe-filter.h (pipe_filter_ii_execute, pipe_filter_gi_create):
+	Likewise.
+	* lib/pipe-filter-ii.c (pipe_filter_ii_execute): Likewise.
+	* lib/pipe-filter-gi.c (pipe_filter_gi_create): Likewise.
+	* lib/javaexec.h (execute_fn): Does not need write access to the
+	elements of prog_argv.
+	* lib/javaexec.c (execute_java_class): Update variable types and remove
+	casts to 'char *'.
+	* lib/csharpexec.h (execute_fn): Does not need write access to the
+	elements of prog_argv.
+	* lib/csharpexec.c (execute_csharp_using_mono,
+	execute_csharp_using_sscli): Update variable types and remove casts to
+	'char *'.
+	* lib/javacomp.c (compile_using_envjavac, compile_using_gcj,
+	compile_using_javac, compile_using_jikes, is_envjavac_gcj,
+	is_envjavac_gcj43, is_gcj_present, is_gcj_43, is_javac_present,
+	is_jikes_present): Update variable types and remove casts to 'char *'.
+	* lib/javaversion.c (execute_and_read_line): Does not need write access
+	to the elements of prog_argv.
+	* lib/csharpcomp.c (compile_csharp_using_mono,
+	compile_csharp_using_sscli): Update variable types and remove casts to
+	'char *'.
+	* tests/test-sh-quote.c (main): Update variable types and remove casts
+	to 'char *'.
+	* tests/test-execute-main.c (main): Update variable types and remove
+	casts to 'char *'.
+	* tests/test-spawn-pipe-main.c (test_pipe): Update variable types and
+	remove casts to 'char *'.
+	* NEWS: Mention the changes.
+
+2020-12-11  Bruno Haible  <br...@clisp.org>
+
 	execute-tests: Fix compilation error with MSVC.
 	* tests/test-execute-child.c (is_device): With _fstat, use
 	'struct _stat', not 'struct stat'.
diff --git a/NEWS b/NEWS
index 747165a..f484881 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,39 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2020-12-11  sh-quote        The argv argument of the 'shell_quote_argv' function
+                            is now of type 'const char * const *'.  You no
+                            longer need to cast read-only strings to 'char *'
+                            when constructing this argument.
+            execute         The prog_argv argument of the 'execute' function
+                            is now of type 'const char * const *'.  You no
+                            longer need to cast read-only strings to 'char *'
+                            when constructing this argument.
+            spawn-pipe      The prog_argv argument of the functions
+                            'create_pipe_out', 'create_pipe_in',
+                            'create_pipe_bidi' is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing this
+                            argument.
+            pipe-filter-gi  The prog_argv argument of the
+                            'pipe_filter_gi_create' function is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing this
+                            argument.
+            pipe-filter-ii  The prog_argv argument of the
+                            'pipe_filter_ii_execute' function is now of type
+                            'const char * const *'.  You no longer need to cast
+                            read-only strings to 'char *' when constructing this
+                            argument.
+            javaexec        The prog_argv argument of the 'execute_fn' function
+                            type is now of type 'const char * const *'.  Update
+                            the signature of all your implementations of this
+                            type.
+            csharpexec      The prog_argv argument of the 'execute_fn' function
+                            type is now of type 'const char * const *'.  Update
+                            the signature of all your implementations of this
+                            type.
+
 2020-12-02  spawn-pipe      The functions 'create_pipe_out', 'create_pipe_in',
                             'create_pipe_bidi' now take a 4th argument
                             'const char *directory'. To maintain the previous
diff --git a/lib/csharpcomp.c b/lib/csharpcomp.c
index 57d2084..cf4e2a5 100644
--- a/lib/csharpcomp.c
+++ b/lib/csharpcomp.c
@@ -76,7 +76,7 @@ compile_csharp_using_mono (const char * const *sources,
          "mcs --version >/dev/null 2>/dev/null"
          and (to exclude an unrelated 'mcs' program on QNX 6)
          "mcs --version 2>/dev/null | grep Mono >/dev/null"  */
-      char *argv[3];
+      const char *argv[3];
       pid_t child;
       int fd[1];
       int exitstatus;
@@ -121,8 +121,8 @@ compile_csharp_using_mono (const char * const *sources,
   if (mcs_present)
     {
       unsigned int argc;
-      char **argv;
-      char **argp;
+      const char **argv;
+      const char **argp;
       pid_t child;
       int fd[1];
       FILE *fp;
@@ -136,7 +136,7 @@ compile_csharp_using_mono (const char * const *sources,
       argc =
         1 + (output_is_library ? 1 : 0) + 1 + libdirs_count + libraries_count
         + (debug ? 1 : 0) + sources_count;
-      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
+      argv = (const char **) xmalloca ((argc + 1) * sizeof (const char *));
 
       argp = argv;
       *argp++ = "mcs";
@@ -179,7 +179,7 @@ compile_csharp_using_mono (const char * const *sources,
               *argp++ = option;
             }
           else
-            *argp++ = (char *) source_file;
+            *argp++ = source_file;
         }
       *argp = NULL;
       /* Ensure argv length was correctly calculated.  */
@@ -232,10 +232,10 @@ compile_csharp_using_mono (const char * const *sources,
            i < 1 + (output_is_library ? 1 : 0)
                + 1 + libdirs_count + libraries_count;
            i++)
-        freea (argv[i]);
+        freea ((char *) argv[i]);
       for (i = 0; i < sources_count; i++)
         if (argv[argc - sources_count + i] != sources[i])
-          freea (argv[argc - sources_count + i]);
+          freea ((char *) argv[argc - sources_count + i]);
       freea (argv);
 
       return (exitstatus != 0);
@@ -263,7 +263,7 @@ compile_csharp_using_sscli (const char * const *sources,
       /* Test for presence of csc:
          "csc -help >/dev/null 2>/dev/null \
           && ! { csc -help 2>/dev/null | grep -i chicken > /dev/null; }"  */
-      char *argv[3];
+      const char *argv[3];
       pid_t child;
       int fd[1];
       int exitstatus;
@@ -312,20 +312,19 @@ compile_csharp_using_sscli (const char * const *sources,
   if (csc_present)
     {
       unsigned int argc;
-      char **argv;
-      char **argp;
+      const char **argv;
+      const char **argp;
       int exitstatus;
       unsigned int i;
 
       argc =
         1 + 1 + 1 + libdirs_count + libraries_count
         + (optimize ? 1 : 0) + (debug ? 1 : 0) + sources_count;
-      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
+      argv = (const char **) xmalloca ((argc + 1) * sizeof (const char *));
 
       argp = argv;
       *argp++ = "csc";
-      *argp++ =
-        (char *) (output_is_library ? "-target:library" : "-target:exe");
+      *argp++ = (output_is_library ? "-target:library" : "-target:exe");
       {
         char *option = (char *) xmalloca (5 + strlen (output_file) + 1);
         memcpy (option, "-out:", 5);
@@ -365,7 +364,7 @@ compile_csharp_using_sscli (const char * const *sources,
               *argp++ = option;
             }
           else
-            *argp++ = (char *) source_file;
+            *argp++ = source_file;
         }
       *argp = NULL;
       /* Ensure argv length was correctly calculated.  */
@@ -384,10 +383,10 @@ compile_csharp_using_sscli (const char * const *sources,
                             true, true, NULL);
 
       for (i = 2; i < 3 + libdirs_count + libraries_count; i++)
-        freea (argv[i]);
+        freea ((char *) argv[i]);
       for (i = 0; i < sources_count; i++)
         if (argv[argc - sources_count + i] != sources[i])
-          freea (argv[argc - sources_count + i]);
+          freea ((char *) argv[argc - sources_count + i]);
       freea (argv);
 
       return (exitstatus != 0);
diff --git a/lib/csharpexec.c b/lib/csharpexec.c
index 5e2aa2c..b6fcc47 100644
--- a/lib/csharpexec.c
+++ b/lib/csharpexec.c
@@ -100,7 +100,7 @@ execute_csharp_using_mono (const char *assembly_path,
     {
       /* Test for presence of mono:
          "mono --version >/dev/null 2>/dev/null"  */
-      char *argv[3];
+      const char *argv[3];
       int exitstatus;
 
       argv[0] = "mono";
@@ -116,7 +116,8 @@ execute_csharp_using_mono (const char *assembly_path,
   if (mono_present)
     {
       char *old_monopath;
-      char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+      const char **argv =
+        (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
       unsigned int i;
       bool err;
 
@@ -124,9 +125,9 @@ execute_csharp_using_mono (const char *assembly_path,
       old_monopath = set_monopath (libdirs, libdirs_count, false, verbose);
 
       argv[0] = "mono";
-      argv[1] = (char *) assembly_path;
+      argv[1] = assembly_path;
       for (i = 0; i <= nargs; i++)
-        argv[2 + i] = (char *) args[i];
+        argv[2 + i] = args[i];
 
       if (verbose)
         {
@@ -163,7 +164,7 @@ execute_csharp_using_sscli (const char *assembly_path,
     {
       /* Test for presence of clix:
          "clix >/dev/null 2>/dev/null ; test $? = 1"  */
-      char *argv[2];
+      const char *argv[2];
       int exitstatus;
 
       argv[0] = "clix";
@@ -178,7 +179,8 @@ execute_csharp_using_sscli (const char *assembly_path,
   if (clix_present)
     {
       char *old_clixpath;
-      char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+      const char **argv =
+        (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
       unsigned int i;
       bool err;
 
@@ -186,9 +188,9 @@ execute_csharp_using_sscli (const char *assembly_path,
       old_clixpath = set_clixpath (libdirs, libdirs_count, false, verbose);
 
       argv[0] = "clix";
-      argv[1] = (char *) assembly_path;
+      argv[1] = assembly_path;
       for (i = 0; i <= nargs; i++)
-        argv[2 + i] = (char *) args[i];
+        argv[2 + i] = args[i];
 
       if (verbose)
         {
diff --git a/lib/csharpexec.h b/lib/csharpexec.h
index c0bb441..088ac06 100644
--- a/lib/csharpexec.h
+++ b/lib/csharpexec.h
@@ -21,7 +21,7 @@
 #include <stdbool.h>
 
 typedef bool execute_fn (const char *progname,
-                         const char *prog_path, char **prog_argv,
+                         const char *prog_path, const char * const *prog_argv,
                          void *private_data);
 
 /* Execute a C# program.
diff --git a/lib/execute.c b/lib/execute.c
index 5821e82..bdc0c0c 100644
--- a/lib/execute.c
+++ b/lib/execute.c
@@ -97,7 +97,7 @@ nonintr_open (const char *pathname, int oflag, mode_t mode)
 
 int
 execute (const char *progname,
-         const char *prog_path, char **prog_argv,
+         const char *prog_path, const char * const *prog_argv,
          const char *directory,
          bool ignore_sigpipe,
          bool null_stdin, bool null_stdout, bool null_stderr,
@@ -158,10 +158,10 @@ execute (const char *progname,
 
   /* Native Windows API.  */
 
-  char *prog_argv_mem_to_free;
+  char *argv_mem_to_free;
 
-  prog_argv = prepare_spawn (prog_argv, &prog_argv_mem_to_free);
-  if (prog_argv == NULL)
+  const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free);
+  if (argv == NULL)
     xalloc_die ();
 
   int exitcode = -1;
@@ -188,17 +188,17 @@ execute (const char *progname,
       HANDLE stderr_handle =
         (HANDLE) _get_osfhandle (null_stderr ? nulloutfd : STDERR_FILENO);
 
-      exitcode = spawnpvech (P_WAIT, prog_path, (const char **) (prog_argv + 1),
-                             (const char **) environ, directory,
+      exitcode = spawnpvech (P_WAIT, prog_path, argv + 1,
+                             (const char * const *) environ, directory,
                              stdin_handle, stdout_handle, stderr_handle);
       if (exitcode == -1 && errno == ENOEXEC)
         {
           /* prog is not a native executable.  Try to execute it as a
              shell script.  Note that prepare_spawn() has already prepended
-             a hidden element "sh.exe" to prog_argv.  */
-          prog_argv[1] = prog_path;
-          exitcode = spawnpvech (P_WAIT, prog_argv[0], (const char **) prog_argv,
-                                 (const char **) environ, directory,
+             a hidden element "sh.exe" to argv.  */
+          argv[1] = prog_path;
+          exitcode = spawnpvech (P_WAIT, argv[0], argv,
+                                 (const char * const *) environ, directory,
                                  stdin_handle, stdout_handle, stderr_handle);
         }
     }
@@ -208,8 +208,8 @@ execute (const char *progname,
     close (nulloutfd);
   if (nullinfd >= 0)
     close (nullinfd);
-  free (prog_argv);
-  free (prog_argv_mem_to_free);
+  free (argv);
+  free (argv_mem_to_free);
   free (prog_path_to_free);
 
   if (termsigp != NULL)
@@ -277,11 +277,11 @@ execute (const char *progname,
                          != 0)))
           || (err = (directory != NULL
                      ? posix_spawn (&child, prog_path, &actions,
-                                    attrs_allocated ? &attrs : NULL, prog_argv,
-                                    environ)
+                                    attrs_allocated ? &attrs : NULL,
+                                    (char * const *) prog_argv, environ)
                      : posix_spawnp (&child, prog_path, &actions,
-                                     attrs_allocated ? &attrs : NULL, prog_argv,
-                                     environ)))
+                                     attrs_allocated ? &attrs : NULL,
+                                     (char * const *) prog_argv, environ)))
              != 0))
     {
       if (actions_allocated)
diff --git a/lib/execute.h b/lib/execute.h
index 34fc989..908d8c5 100644
--- a/lib/execute.h
+++ b/lib/execute.h
@@ -46,7 +46,7 @@
    It is recommended that no signal is blocked or ignored while execute()
    is called.  See spawn-pipe.h for the reason.  */
 extern int execute (const char *progname,
-                    const char *prog_path, char **prog_argv,
+                    const char *prog_path, const char * const *prog_argv,
                     const char *directory,
                     bool ignore_sigpipe,
                     bool null_stdin, bool null_stdout, bool null_stderr,
diff --git a/lib/javacomp.c b/lib/javacomp.c
index c24bb69..ca7a6fe 100644
--- a/lib/javacomp.c
+++ b/lib/javacomp.c
@@ -288,7 +288,7 @@ compile_using_envjavac (const char *javac,
   bool err;
   unsigned int command_length;
   char *command;
-  char *argv[4];
+  const char *argv[4];
   int exitstatus;
   unsigned int i;
   char *p;
@@ -367,8 +367,8 @@ compile_using_gcj (const char * const *java_sources,
 {
   bool err;
   unsigned int argc;
-  char **argv;
-  char **argp;
+  const char **argv;
+  const char **argp;
   char *fsource_arg;
   char *ftarget_arg;
   int exitstatus;
@@ -378,7 +378,7 @@ compile_using_gcj (const char * const *java_sources,
     2 + (no_assert_option ? 1 : 0) + (fsource_option ? 1 : 0)
     + (ftarget_option ? 1 : 0) + (optimize ? 1 : 0) + (debug ? 1 : 0)
     + (directory != NULL ? 2 : 0) + java_sources_count;
-  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
+  argv = (const char **) xmalloca ((argc + 1) * sizeof (const char *));
 
   argp = argv;
   *argp++ = "gcj";
@@ -410,10 +410,10 @@ compile_using_gcj (const char * const *java_sources,
   if (directory != NULL)
     {
       *argp++ = "-d";
-      *argp++ = (char *) directory;
+      *argp++ = directory;
     }
   for (i = 0; i < java_sources_count; i++)
-    *argp++ = (char *) java_sources[i];
+    *argp++ = java_sources[i];
   *argp = NULL;
   /* Ensure argv length was correctly calculated.  */
   if (argp - argv != argc)
@@ -453,27 +453,27 @@ compile_using_javac (const char * const *java_sources,
 {
   bool err;
   unsigned int argc;
-  char **argv;
-  char **argp;
+  const char **argv;
+  const char **argp;
   int exitstatus;
   unsigned int i;
 
   argc =
     1 + (source_option ? 2 : 0) + (target_option ? 2 : 0) + (optimize ? 1 : 0)
     + (debug ? 1 : 0) + (directory != NULL ? 2 : 0) + java_sources_count;
-  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
+  argv = (const char **) xmalloca ((argc + 1) * sizeof (const char *));
 
   argp = argv;
   *argp++ = "javac";
   if (source_option)
     {
       *argp++ = "-source";
-      *argp++ = (char *) source_version;
+      *argp++ = source_version;
     }
   if (target_option)
     {
       *argp++ = "-target";
-      *argp++ = (char *) target_version;
+      *argp++ = target_version;
     }
   if (optimize)
     *argp++ = "-O";
@@ -482,10 +482,10 @@ compile_using_javac (const char * const *java_sources,
   if (directory != NULL)
     {
       *argp++ = "-d";
-      *argp++ = (char *) directory;
+      *argp++ = directory;
     }
   for (i = 0; i < java_sources_count; i++)
-    *argp++ = (char *) java_sources[i];
+    *argp++ = java_sources[i];
   *argp = NULL;
   /* Ensure argv length was correctly calculated.  */
   if (argp - argv != argc)
@@ -519,15 +519,15 @@ compile_using_jikes (const char * const *java_sources,
 {
   bool err;
   unsigned int argc;
-  char **argv;
-  char **argp;
+  const char **argv;
+  const char **argp;
   int exitstatus;
   unsigned int i;
 
   argc =
     1 + (optimize ? 1 : 0) + (debug ? 1 : 0) + (directory != NULL ? 2 : 0)
     + java_sources_count;
-  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
+  argv = (const char **) xmalloca ((argc + 1) * sizeof (const char *));
 
   argp = argv;
   *argp++ = "jikes";
@@ -538,10 +538,10 @@ compile_using_jikes (const char * const *java_sources,
   if (directory != NULL)
     {
       *argp++ = "-d";
-      *argp++ = (char *) directory;
+      *argp++ = directory;
     }
   for (i = 0; i < java_sources_count; i++)
-    *argp++ = (char *) java_sources[i];
+    *argp++ = java_sources[i];
   *argp = NULL;
   /* Ensure argv length was correctly calculated.  */
   if (argp - argv != argc)
@@ -635,7 +635,7 @@ is_envjavac_gcj (const char *javac)
          "$JAVAC --version 2>/dev/null | sed -e 1q | grep gcj > /dev/null"  */
       unsigned int command_length;
       char *command;
-      char *argv[4];
+      const char *argv[4];
       pid_t child;
       int fd[1];
       FILE *fp;
@@ -717,7 +717,7 @@ is_envjavac_gcj43 (const char *javac)
           | sed -e '/^4\.[012]/d' | grep '^[4-9]' >/dev/null"  */
       unsigned int command_length;
       char *command;
-      char *argv[4];
+      const char *argv[4];
       pid_t child;
       int fd[1];
       FILE *fp;
@@ -1406,7 +1406,7 @@ is_gcj_present (void)
          "gcj --version 2> /dev/null | \
           sed -e 's,^[^0-9]*,,' -e 1q | \
           sed -e '/^3\.[01]/d' | grep '^[3-9]' > /dev/null"  */
-      char *argv[3];
+      const char *argv[3];
       pid_t child;
       int fd[1];
       int exitstatus;
@@ -1522,7 +1522,7 @@ is_gcj_43 (void)
          "gcj --version 2> /dev/null | \
           sed -e 's,^[^0-9]*,,' -e 1q | \
           sed -e '/^4\.[012]/d' | grep '^[4-9]'"  */
-      char *argv[3];
+      const char *argv[3];
       pid_t child;
       int fd[1];
       int exitstatus;
@@ -1871,7 +1871,7 @@ is_javac_present (void)
   if (!javac_tested)
     {
       /* Test for presence of javac: "javac 2> /dev/null ; test $? -le 2"  */
-      char *argv[2];
+      const char *argv[2];
       int exitstatus;
 
       argv[0] = "javac";
@@ -2138,7 +2138,7 @@ is_jikes_present (void)
   if (!jikes_tested)
     {
       /* Test for presence of jikes: "jikes 2> /dev/null ; test $? = 1"  */
-      char *argv[2];
+      const char *argv[2];
       int exitstatus;
 
       argv[0] = "jikes";
diff --git a/lib/javaexec.c b/lib/javaexec.c
index d486fb8..613c7fc 100644
--- a/lib/javaexec.c
+++ b/lib/javaexec.c
@@ -96,7 +96,8 @@ execute_java_class (const char *class_name,
     {
       char *exe_pathname = xconcatenated_filename (exe_dir, class_name, EXEEXT);
       char *old_classpath;
-      char **argv = (char **) xmalloca ((1 + nargs + 1) * sizeof (char *));
+      const char **argv =
+        (const char **) xmalloca ((1 + nargs + 1) * sizeof (const char *));
       unsigned int i;
 
       /* Set CLASSPATH.  */
@@ -106,7 +107,7 @@ execute_java_class (const char *class_name,
 
       argv[0] = exe_pathname;
       for (i = 0; i <= nargs; i++)
-        argv[1 + i] = (char *) args[i];
+        argv[1 + i] = args[i];
 
       if (verbose)
         {
@@ -136,7 +137,7 @@ execute_java_class (const char *class_name,
         char *old_classpath;
         unsigned int command_length;
         char *command;
-        char *argv[4];
+        const char *argv[4];
         const char * const *arg;
         char *p;
 
@@ -202,7 +203,7 @@ execute_java_class (const char *class_name,
     if (!gij_tested)
       {
         /* Test for presence of gij: "gij --version > /dev/null"  */
-        char *argv[3];
+        const char *argv[3];
         int exitstatus;
 
         argv[0] = "gij";
@@ -218,7 +219,8 @@ execute_java_class (const char *class_name,
     if (gij_present)
       {
         char *old_classpath;
-        char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+        const char **argv =
+          (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
         unsigned int i;
 
         /* Set CLASSPATH.  */
@@ -227,9 +229,9 @@ execute_java_class (const char *class_name,
                          verbose);
 
         argv[0] = "gij";
-        argv[1] = (char *) class_name;
+        argv[1] = class_name;
         for (i = 0; i <= nargs; i++)
-          argv[2 + i] = (char *) args[i];
+          argv[2 + i] = args[i];
 
         if (verbose)
           {
@@ -256,7 +258,7 @@ execute_java_class (const char *class_name,
     if (!java_tested)
       {
         /* Test for presence of java: "java -version 2> /dev/null"  */
-        char *argv[3];
+        const char *argv[3];
         int exitstatus;
 
         argv[0] = "java";
@@ -272,7 +274,8 @@ execute_java_class (const char *class_name,
     if (java_present)
       {
         char *old_classpath;
-        char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+        const char **argv =
+          (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
         unsigned int i;
 
         /* Set CLASSPATH.  We don't use the "-classpath ..." option because
@@ -283,9 +286,9 @@ execute_java_class (const char *class_name,
                          verbose);
 
         argv[0] = "java";
-        argv[1] = (char *) class_name;
+        argv[1] = class_name;
         for (i = 0; i <= nargs; i++)
-          argv[2 + i] = (char *) args[i];
+          argv[2 + i] = args[i];
 
         if (verbose)
           {
@@ -312,7 +315,7 @@ execute_java_class (const char *class_name,
     if (!jre_tested)
       {
         /* Test for presence of jre: "jre 2> /dev/null ; test $? = 1"  */
-        char *argv[2];
+        const char *argv[2];
         int exitstatus;
 
         argv[0] = "jre";
@@ -327,7 +330,8 @@ execute_java_class (const char *class_name,
     if (jre_present)
       {
         char *old_classpath;
-        char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+        const char **argv =
+          (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
         unsigned int i;
 
         /* Set CLASSPATH.  We don't use the "-classpath ..." option because
@@ -338,9 +342,9 @@ execute_java_class (const char *class_name,
                          verbose);
 
         argv[0] = "jre";
-        argv[1] = (char *) class_name;
+        argv[1] = class_name;
         for (i = 0; i <= nargs; i++)
-          argv[2 + i] = (char *) args[i];
+          argv[2 + i] = args[i];
 
         if (verbose)
           {
@@ -369,7 +373,7 @@ execute_java_class (const char *class_name,
     if (!jview_tested)
       {
         /* Test for presence of jview: "jview -? >nul ; test $? = 1"  */
-        char *argv[3];
+        const char *argv[3];
         int exitstatus;
 
         argv[0] = "jview";
@@ -385,7 +389,8 @@ execute_java_class (const char *class_name,
     if (jview_present)
       {
         char *old_classpath;
-        char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
+        const char **argv =
+          (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
         unsigned int i;
 
         /* Set CLASSPATH.  */
@@ -394,9 +399,9 @@ execute_java_class (const char *class_name,
                          verbose);
 
         argv[0] = "jview";
-        argv[1] = (char *) class_name;
+        argv[1] = class_name;
         for (i = 0; i <= nargs; i++)
-          argv[2 + i] = (char *) args[i];
+          argv[2 + i] = args[i];
 
         if (verbose)
           {
diff --git a/lib/javaexec.h b/lib/javaexec.h
index c17a694..9480e73 100644
--- a/lib/javaexec.h
+++ b/lib/javaexec.h
@@ -21,7 +21,7 @@
 #include <stdbool.h>
 
 typedef bool execute_fn (const char *progname,
-                         const char *prog_path, char **prog_argv,
+                         const char *prog_path, const char * const *prog_argv,
                          void *private_data);
 
 /* Execute a Java class.
diff --git a/lib/javaversion.c b/lib/javaversion.c
index e50c499..2bfb08f 100644
--- a/lib/javaversion.c
+++ b/lib/javaversion.c
@@ -52,7 +52,7 @@ struct locals
 
 static bool
 execute_and_read_line (const char *progname,
-                       const char *prog_path, char **prog_argv,
+                       const char *prog_path, const char * const *prog_argv,
                        void *private_data)
 {
   struct locals *l = (struct locals *) private_data;
diff --git a/lib/os2-spawn.c b/lib/os2-spawn.c
index 53a35f6..ac425a3 100644
--- a/lib/os2-spawn.c
+++ b/lib/os2-spawn.c
@@ -92,11 +92,11 @@ undup_safer_noinherit (int tempfd, int origfd)
     }
 }
 
-char **
-prepare_spawn (char **argv, char **mem_to_free)
+const char **
+prepare_spawn (const char * const *argv, char **mem_to_free)
 {
   size_t argc;
-  char **new_argv;
+  const char **new_argv;
   size_t i;
 
   /* Count number of arguments.  */
@@ -104,7 +104,7 @@ prepare_spawn (char **argv, char **mem_to_free)
     ;
 
   /* Allocate new argument vector.  */
-  new_argv = (char **) malloc ((1 + argc + 1) * sizeof (char *));
+  new_argv = (const char **) malloc ((1 + argc + 1) * sizeof (const char *));
   if (new_argv == NULL)
     return NULL;
 
diff --git a/lib/os2-spawn.h b/lib/os2-spawn.h
index 4c8c6a8..419f7f9 100644
--- a/lib/os2-spawn.h
+++ b/lib/os2-spawn.h
@@ -27,6 +27,7 @@ extern int dup_safer_noinherit (int fd);
 extern void undup_safer_noinherit (int tempfd, int origfd);
 
 /* Prepares an argument vector before calling spawn().  */
-extern char ** prepare_spawn (char **argv, char **mem_to_free);
+extern const char ** prepare_spawn (const char * const *argv,
+                                    char **mem_to_free);
 
 #endif /* _OS2_SPAWN_H */
diff --git a/lib/pipe-filter-gi.c b/lib/pipe-filter-gi.c
index 7528053..80617d7 100644
--- a/lib/pipe-filter-gi.c
+++ b/lib/pipe-filter-gi.c
@@ -485,7 +485,7 @@ filter_retcode (struct pipe_filter_gi *filter)
 
 struct pipe_filter_gi *
 pipe_filter_gi_create (const char *progname,
-                       const char *prog_path, const char **prog_argv,
+                       const char *prog_path, const char * const *prog_argv,
                        bool null_stderr, bool exit_on_error,
                        prepare_read_fn prepare_read,
                        done_read_fn done_read,
@@ -497,7 +497,7 @@ pipe_filter_gi_create (const char *progname,
     (struct pipe_filter_gi *) xmalloc (sizeof (struct pipe_filter_gi));
 
   /* Open a bidirectional pipe to a subprocess.  */
-  filter->child = create_pipe_bidi (progname, prog_path, (char **) prog_argv,
+  filter->child = create_pipe_bidi (progname, prog_path, prog_argv,
                                     NULL, null_stderr, true, exit_on_error,
                                     filter->fd);
   filter->progname = progname;
diff --git a/lib/pipe-filter-ii.c b/lib/pipe-filter-ii.c
index 384a59b..2342088 100644
--- a/lib/pipe-filter-ii.c
+++ b/lib/pipe-filter-ii.c
@@ -255,7 +255,7 @@ reader_thread_func (void *thread_arg)
 
 int
 pipe_filter_ii_execute (const char *progname,
-                        const char *prog_path, const char **prog_argv,
+                        const char *prog_path, const char * const *prog_argv,
                         bool null_stderr, bool exit_on_error,
                         prepare_write_fn prepare_write,
                         done_write_fn done_write,
@@ -270,7 +270,7 @@ pipe_filter_ii_execute (const char *progname,
 #endif
 
   /* Open a bidirectional pipe to a subprocess.  */
-  child = create_pipe_bidi (progname, prog_path, (char **) prog_argv,
+  child = create_pipe_bidi (progname, prog_path, prog_argv,
                             NULL, null_stderr, true, exit_on_error,
                             fd);
   if (child == -1)
diff --git a/lib/pipe-filter.h b/lib/pipe-filter.h
index 9e2c966..71ef70b 100644
--- a/lib/pipe-filter.h
+++ b/lib/pipe-filter.h
@@ -133,7 +133,8 @@ typedef void (*done_read_fn) (void *data_read, size_t num_bytes_read,
    - the positive exit code of the subprocess if that failed.  */
 extern int
        pipe_filter_ii_execute (const char *progname,
-                               const char *prog_path, const char **prog_argv,
+                               const char *prog_path,
+                               const char * const *prog_argv,
                                bool null_stderr, bool exit_on_error,
                                prepare_write_fn prepare_write,
                                done_write_fn done_write,
@@ -179,7 +180,8 @@ struct pipe_filter_gi;
    Return the freshly created 'struct pipe_filter_gi'.  */
 extern struct pipe_filter_gi *
        pipe_filter_gi_create (const char *progname,
-                              const char *prog_path, const char **prog_argv,
+                              const char *prog_path,
+                              const char * const *prog_argv,
                               bool null_stderr, bool exit_on_error,
                               prepare_read_fn prepare_read,
                               done_read_fn done_read,
diff --git a/lib/sh-quote.c b/lib/sh-quote.c
index 1508d4e..8181c7a 100644
--- a/lib/sh-quote.c
+++ b/lib/sh-quote.c
@@ -69,11 +69,11 @@ shell_quote (const char *string)
 /* Returns a freshly allocated string containing all argument strings, quoted,
    separated through spaces.  */
 char *
-shell_quote_argv (char * const *argv)
+shell_quote_argv (const char * const *argv)
 {
   if (*argv != NULL)
     {
-      char * const *argp;
+      const char * const *argp;
       size_t length;
       char *command;
       char *p;
diff --git a/lib/sh-quote.h b/lib/sh-quote.h
index 8b06355..9c6f2aa 100644
--- a/lib/sh-quote.h
+++ b/lib/sh-quote.h
@@ -40,7 +40,7 @@ extern char * shell_quote (const char *string);
 
 /* Returns a freshly allocated string containing all argument strings, quoted,
    separated through spaces.  */
-extern char * shell_quote_argv (char * const *argv);
+extern char * shell_quote_argv (const char * const *argv);
 
 #ifdef __cplusplus
 }
diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c
index c73872b..ba07d20 100644
--- a/lib/spawn-pipe.c
+++ b/lib/spawn-pipe.c
@@ -123,7 +123,8 @@ nonintr_open (const char *pathname, int oflag, mode_t mode)
  */
 static pid_t
 create_pipe (const char *progname,
-             const char *prog_path, char **prog_argv,
+             const char *prog_path,
+             const char * const *prog_argv,
              const char *directory,
              bool pipe_stdin, bool pipe_stdout,
              const char *prog_stdin, const char *prog_stdout,
@@ -187,7 +188,7 @@ create_pipe (const char *progname,
      using the low-level functions CreatePipe(), DuplicateHandle(),
      CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
      and cvs source code.  */
-  char *prog_argv_mem_to_free;
+  char *argv_mem_to_free;
   int ifd[2];
   int ofd[2];
   int child;
@@ -195,8 +196,8 @@ create_pipe (const char *progname,
   int stdinfd;
   int stdoutfd;
 
-  prog_argv = prepare_spawn (prog_argv, &prog_argv_mem_to_free);
-  if (prog_argv == NULL)
+  const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free);
+  if (argv == NULL)
     xalloc_die ();
 
   if (pipe_stdout)
@@ -281,17 +282,17 @@ create_pipe (const char *progname,
       HANDLE stderr_handle =
         (HANDLE) _get_osfhandle (null_stderr ? nulloutfd : STDERR_FILENO);
 
-      child = spawnpvech (P_NOWAIT, prog_path, (const char **) (prog_argv + 1),
-                          (const char **) environ, directory,
+      child = spawnpvech (P_NOWAIT, prog_path, argv + 1,
+                          (const char * const *) environ, directory,
                           stdin_handle, stdout_handle, stderr_handle);
       if (child == -1 && errno == ENOEXEC)
         {
           /* prog is not a native executable.  Try to execute it as a
              shell script.  Note that prepare_spawn() has already prepended
-             a hidden element "sh.exe" to prog_argv.  */
-          prog_argv[1] = prog_path;
-          child = spawnpvech (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
-                              (const char **) environ, directory,
+             a hidden element "sh.exe" to argv.  */
+          argv[1] = prog_path;
+          child = spawnpvech (P_NOWAIT, argv[0], argv,
+                              (const char * const *) environ, directory,
                               stdin_handle, stdout_handle, stderr_handle);
         }
     }
@@ -357,14 +358,14 @@ create_pipe (const char *progname,
        but it inherits all open()ed or dup2()ed file handles (which is what
        we want in the case of STD*_FILENO).  */
     {
-      child = _spawnvpe (P_NOWAIT, prog_path, (const char **) (prog_argv + 1),
+      child = _spawnvpe (P_NOWAIT, prog_path, argv + 1,
                          (const char **) environ);
       if (child == -1 && errno == ENOEXEC)
         {
           /* prog is not a native executable.  Try to execute it as a
              shell script.  Note that prepare_spawn() has already prepended
-             a hidden element "sh.exe" to prog_argv.  */
-          child = _spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
+             a hidden element "sh.exe" to argv.  */
+          child = _spawnvpe (P_NOWAIT, argv[0], argv,
                              (const char **) environ);
         }
     }
@@ -391,8 +392,8 @@ create_pipe (const char *progname,
     close (ifd[1]);
 # endif
 
-  free (prog_argv);
-  free (prog_argv_mem_to_free);
+  free (argv);
+  free (argv_mem_to_free);
   free (prog_path_to_free);
 
   if (child == -1)
@@ -501,11 +502,11 @@ create_pipe (const char *progname,
                          != 0)))
           || (err = (directory != NULL
                      ? posix_spawn (&child, prog_path, &actions,
-                                    attrs_allocated ? &attrs : NULL, prog_argv,
-                                    environ)
+                                    attrs_allocated ? &attrs : NULL,
+                                    (char * const *) prog_argv, environ)
                      : posix_spawnp (&child, prog_path, &actions,
-                                     attrs_allocated ? &attrs : NULL, prog_argv,
-                                     environ)))
+                                     attrs_allocated ? &attrs : NULL,
+                                     (char * const *) prog_argv, environ)))
              != 0))
     {
       if (actions_allocated)
@@ -570,7 +571,7 @@ create_pipe (const char *progname,
  */
 pid_t
 create_pipe_bidi (const char *progname,
-                  const char *prog_path, char **prog_argv,
+                  const char *prog_path, const char * const *prog_argv,
                   const char *directory,
                   bool null_stderr,
                   bool slave_process, bool exit_on_error,
@@ -592,7 +593,7 @@ create_pipe_bidi (const char *progname,
  */
 pid_t
 create_pipe_in (const char *progname,
-                const char *prog_path, char **prog_argv,
+                const char *prog_path, const char * const *prog_argv,
                 const char *directory,
                 const char *prog_stdin, bool null_stderr,
                 bool slave_process, bool exit_on_error,
@@ -617,7 +618,7 @@ create_pipe_in (const char *progname,
  */
 pid_t
 create_pipe_out (const char *progname,
-                 const char *prog_path, char **prog_argv,
+                 const char *prog_path, const char * const *prog_argv,
                  const char *directory,
                  const char *prog_stdout, bool null_stderr,
                  bool slave_process, bool exit_on_error,
diff --git a/lib/spawn-pipe.h b/lib/spawn-pipe.h
index 02856a8..a624822 100644
--- a/lib/spawn-pipe.h
+++ b/lib/spawn-pipe.h
@@ -96,7 +96,8 @@ extern "C" {
  * signal and the EPIPE error code.
  */
 extern pid_t create_pipe_out (const char *progname,
-                              const char *prog_path, char **prog_argv,
+                              const char *prog_path,
+                              const char * const *prog_argv,
                               const char *directory,
                               const char *prog_stdout, bool null_stderr,
                               bool slave_process, bool exit_on_error,
@@ -110,7 +111,8 @@ extern pid_t create_pipe_out (const char *progname,
  *
  */
 extern pid_t create_pipe_in (const char *progname,
-                             const char *prog_path, char **prog_argv,
+                             const char *prog_path,
+                             const char * const *prog_argv,
                              const char *directory,
                              const char *prog_stdin, bool null_stderr,
                              bool slave_process, bool exit_on_error,
@@ -139,7 +141,8 @@ extern pid_t create_pipe_in (const char *progname,
  *    input.  But you are currently busy reading from it.
  */
 extern pid_t create_pipe_bidi (const char *progname,
-                               const char *prog_path, char **prog_argv,
+                               const char *prog_path,
+                               const char * const *prog_argv,
                                const char *directory,
                                bool null_stderr,
                                bool slave_process, bool exit_on_error,
diff --git a/lib/windows-spawn.c b/lib/windows-spawn.c
index d252f32..88a6b4d 100644
--- a/lib/windows-spawn.c
+++ b/lib/windows-spawn.c
@@ -122,11 +122,11 @@ quoted_arg_string (const char *string, char *mem)
   return p;
 }
 
-char **
-prepare_spawn (char **argv, char **mem_to_free)
+const char **
+prepare_spawn (const char * const *argv, char **mem_to_free)
 {
   size_t argc;
-  char **new_argv;
+  const char **new_argv;
   size_t i;
 
   /* Count number of arguments.  */
@@ -134,7 +134,7 @@ prepare_spawn (char **argv, char **mem_to_free)
     ;
 
   /* Allocate new argument vector.  */
-  new_argv = (char **) malloc ((1 + argc + 1) * sizeof (char *));
+  new_argv = (const char **) malloc ((1 + argc + 1) * sizeof (const char *));
 
   /* Add an element upfront that can be used when argv[0] turns out to be a
      script, not a program.
diff --git a/lib/windows-spawn.h b/lib/windows-spawn.h
index ddbbffa..77720d5 100644
--- a/lib/windows-spawn.h
+++ b/lib/windows-spawn.h
@@ -62,7 +62,8 @@
    allocated as well.  In case of memory allocation failure, NULL is returned,
    with errno set.
  */
-extern char ** prepare_spawn (char **argv, char **mem_to_free);
+extern const char ** prepare_spawn (const char * const *argv,
+                                    char **mem_to_free);
 
 /* Creates a subprocess.
    MODE is either P_WAIT or P_NOWAIT.
diff --git a/tests/test-execute-main.c b/tests/test-execute-main.c
index 755209e..c58a62d 100644
--- a/tests/test-execute-main.c
+++ b/tests/test-execute-main.c
@@ -63,7 +63,7 @@ main (int argc, char *argv[])
     case 0:
       {
         /* Check an invocation without arguments.  Check the exit code.  */
-        char *prog_argv[2] = { prog_path, NULL };
+        const char *prog_argv[2] = { prog_path, NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 40);
@@ -72,7 +72,7 @@ main (int argc, char *argv[])
     case 1:
       {
         /* Check an invocation of a non-existent program.  */
-        char *prog_argv[3] = { "./non-existent", NULL };
+        const char *prog_argv[3] = { "./non-existent", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 127);
@@ -81,20 +81,20 @@ main (int argc, char *argv[])
     case 2:
       {
         /* Check argument passing.  */
-        char *prog_argv[13] =
+        const char *prog_argv[13] =
           {
             prog_path,
-            (char *) "2",
-            (char *) "abc def",
-            (char *) "abc\"def\"ghi",
-            (char *) "xyz\"",
-            (char *) "abc\\def\\ghi",
-            (char *) "xyz\\",
-            (char *) "???",
-            (char *) "***",
-            (char *) "",
-            (char *) "foo",
-            (char *) "",
+            "2",
+            "abc def",
+            "abc\"def\"ghi",
+            "xyz\"",
+            "abc\\def\\ghi",
+            "xyz\\",
+            "???",
+            "***",
+            "",
+            "foo",
+            "",
             NULL
           };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
@@ -106,7 +106,7 @@ main (int argc, char *argv[])
       #if !(defined _WIN32 && !defined __CYGWIN__)
       {
         /* Check SIGPIPE handling with ignore_sigpipe = false.  */
-        char *prog_argv[3] = { prog_path, (char *) "3", NULL };
+        const char *prog_argv[3] = { prog_path, "3", NULL };
         int termsig = 0xDEADBEEF;
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, &termsig);
@@ -119,7 +119,7 @@ main (int argc, char *argv[])
       #if !(defined _WIN32 && !defined __CYGWIN__)
       {
         /* Check SIGPIPE handling with ignore_sigpipe = true.  */
-        char *prog_argv[3] = { prog_path, (char *) "4", NULL };
+        const char *prog_argv[3] = { prog_path, "4", NULL };
         int termsig = 0xDEADBEEF;
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            true, false, false, false, true, false, &termsig);
@@ -131,7 +131,7 @@ main (int argc, char *argv[])
     case 5:
       {
         /* Check other signal.  */
-        char *prog_argv[3] = { prog_path, (char *) "5", NULL };
+        const char *prog_argv[3] = { prog_path, "5", NULL };
         int termsig = 0xDEADBEEF;
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, &termsig);
@@ -154,7 +154,7 @@ main (int argc, char *argv[])
         fp = freopen (BASE ".tmp", "r", stdin);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "6", NULL };
+        const char *prog_argv[3] = { prog_path, "6", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -173,7 +173,7 @@ main (int argc, char *argv[])
         fp = freopen (BASE ".tmp", "r", stdin);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "7", NULL };
+        const char *prog_argv[3] = { prog_path, "7", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, true, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -188,7 +188,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (BASE ".tmp", "w", stdout);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "8", NULL };
+        const char *prog_argv[3] = { prog_path, "8", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -208,7 +208,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (DEV_NULL, "w", stdout);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "9", NULL };
+        const char *prog_argv[3] = { prog_path, "9", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -220,7 +220,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (BASE ".tmp", "w", stdout);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "10", NULL };
+        const char *prog_argv[3] = { prog_path, "10", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, true, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -240,7 +240,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (BASE ".tmp", "w", stderr);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "11", NULL };
+        const char *prog_argv[3] = { prog_path, "11", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -260,7 +260,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (DEV_NULL, "w", stderr);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "12", NULL };
+        const char *prog_argv[3] = { prog_path, "12", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -272,7 +272,7 @@ main (int argc, char *argv[])
         FILE *fp = freopen (BASE ".tmp", "w", stderr);
         ASSERT (fp != NULL);
 
-        char *prog_argv[3] = { prog_path, (char *) "13", NULL };
+        const char *prog_argv[3] = { prog_path, "13", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, true, true, false, NULL);
         ASSERT (ret == 0);
@@ -290,7 +290,7 @@ main (int argc, char *argv[])
       {
         /* Check file descriptors >= 3 can be inherited.  */
         ASSERT (dup2 (STDOUT_FILENO, 10) >= 0);
-        char *prog_argv[3] = { prog_path, (char *) "14", NULL };
+        const char *prog_argv[3] = { prog_path, "14", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            true, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -300,7 +300,7 @@ main (int argc, char *argv[])
       {
         /* Check file descriptors >= 3 can be inherited.  */
         ASSERT (fcntl (STDOUT_FILENO, F_DUPFD, 10) >= 0);
-        char *prog_argv[3] = { prog_path, (char *) "15", NULL };
+        const char *prog_argv[3] = { prog_path, "15", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            true, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -310,7 +310,7 @@ main (int argc, char *argv[])
       {
         /* Check file descriptors >= 3 with O_CLOEXEC bit are not inherited.  */
         ASSERT (fcntl (STDOUT_FILENO, F_DUPFD_CLOEXEC, 10) >= 0);
-        char *prog_argv[3] = { prog_path, (char *) "16", NULL };
+        const char *prog_argv[3] = { prog_path, "16", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            true, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -335,7 +335,7 @@ main (int argc, char *argv[])
         ASSERT (read (fd, buf, sizeof (buf)) == sizeof (buf));
         /* The file position is now 2.  */
 
-        char *prog_argv[3] = { prog_path, (char *) "17", NULL };
+        const char *prog_argv[3] = { prog_path, "17", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -359,7 +359,7 @@ main (int argc, char *argv[])
         ASSERT (write (fd, "Foo", 3) == 3);
         /* The file position is now 3.  */
 
-        char *prog_argv[3] = { prog_path, (char *) "18", NULL };
+        const char *prog_argv[3] = { prog_path, "18", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
@@ -395,7 +395,7 @@ main (int argc, char *argv[])
         close (fd_out);
         fd_out = 11;
 
-        char *prog_argv[3] = { prog_path, (char *) "19", NULL };
+        const char *prog_argv[3] = { prog_path, "19", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         #if defined _WIN32 && ! defined __CYGWIN__
@@ -419,7 +419,7 @@ main (int argc, char *argv[])
         ASSERT (dup2 (STDOUT_FILENO, 11) >= 0);
         int fd_out = 11;
 
-        char *prog_argv[3] = { prog_path, (char *) "20", NULL };
+        const char *prog_argv[3] = { prog_path, "20", NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, NULL,
                            false, false, false, false, true, false, NULL);
         #if defined _WIN32 && ! defined __CYGWIN__
@@ -445,7 +445,7 @@ main (int argc, char *argv[])
         ASSERT (getcwd (cwd, sizeof (cwd)) != NULL);
         #endif
 
-        char *prog_argv[4] = { prog_path, (char *) "21", cwd, NULL };
+        const char *prog_argv[4] = { prog_path, "21", cwd, NULL };
         int ret = execute (progname, prog_argv[0], prog_argv, BASE ".sub",
                            false, false, false, false, true, false, NULL);
         ASSERT (ret == 0);
diff --git a/tests/test-sh-quote.c b/tests/test-sh-quote.c
index 8d2d7e2..6b4fb18 100644
--- a/tests/test-sh-quote.c
+++ b/tests/test-sh-quote.c
@@ -172,7 +172,7 @@ main (void)
 
   /* Check the shell_quote_argv function.  */
   {
-    char *argv[1];
+    const char *argv[1];
     char *result;
     argv[0] = NULL;
     result = shell_quote_argv (argv);
@@ -180,19 +180,19 @@ main (void)
     free (result);
   }
   {
-    char *argv[2];
+    const char *argv[2];
     char *result;
-    argv[0] = (char *) "foo bar/baz";
+    argv[0] = "foo bar/baz";
     argv[1] = NULL;
     result = shell_quote_argv (argv);
     ASSERT (strcmp (result, "'foo bar/baz'") == 0); /* or "\"foo bar/baz\"" */
     free (result);
   }
   {
-    char *argv[3];
+    const char *argv[3];
     char *result;
-    argv[0] = (char *) "foo bar/baz";
-    argv[1] = (char *) "$";
+    argv[0] = "foo bar/baz";
+    argv[1] = "$";
     argv[2] = NULL;
     result = shell_quote_argv (argv);
     ASSERT (strcmp (result, "'foo bar/baz' '$'") == 0); /* or "\"foo bar/baz\" \"\\$\"" */
diff --git a/tests/test-spawn-pipe-main.c b/tests/test-spawn-pipe-main.c
index fe4f94e..cc61f8e 100644
--- a/tests/test-spawn-pipe-main.c
+++ b/tests/test-spawn-pipe-main.c
@@ -44,13 +44,13 @@ static void
 test_pipe (const char *prog, bool stderr_closed)
 {
   int fd[2];
-  char *argv[3];
+  const char *argv[3];
   pid_t pid;
   char buffer[2] = { 'a', 't' };
 
   /* Set up child.  */
-  argv[0] = (char *) prog;
-  argv[1] = (char *) (stderr_closed ? "1" : "0");
+  argv[0] = prog;
+  argv[1] = (stderr_closed ? "1" : "0");
   argv[2] = NULL;
   pid = create_pipe_bidi (prog, prog, argv, NULL, false, true, true, fd);
   ASSERT (0 <= pid);
-- 
2.7.4

Reply via email to