+2020-12-11 Bruno Haible <bruno@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 <bruno@clisp.org>
execute-tests: Fix compilation error with MSVC.
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
"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;
if (mcs_present)
{
unsigned int argc;
- char **argv;
- char **argp;
+ const char **argv;
+ const char **argp;
pid_t child;
int fd[1];
FILE *fp;
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";
*argp++ = option;
}
else
- *argp++ = (char *) source_file;
+ *argp++ = source_file;
}
*argp = NULL;
/* Ensure argv length was correctly calculated. */
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);
/* 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;
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);
*argp++ = option;
}
else
- *argp++ = (char *) source_file;
+ *argp++ = source_file;
}
*argp = NULL;
/* Ensure argv length was correctly calculated. */
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);
{
/* Test for presence of mono:
"mono --version >/dev/null 2>/dev/null" */
- char *argv[3];
+ const char *argv[3];
int exitstatus;
argv[0] = "mono";
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;
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)
{
{
/* 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";
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;
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)
{
#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.
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,
/* 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;
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);
}
}
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)
!= 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)
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,
bool err;
unsigned int command_length;
char *command;
- char *argv[4];
+ const char *argv[4];
int exitstatus;
unsigned int i;
char *p;
{
bool err;
unsigned int argc;
- char **argv;
- char **argp;
+ const char **argv;
+ const char **argp;
char *fsource_arg;
char *ftarget_arg;
int exitstatus;
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";
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)
{
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";
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)
{
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";
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)
"$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;
| 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;
"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;
"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;
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";
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";
{
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. */
argv[0] = exe_pathname;
for (i = 0; i <= nargs; i++)
- argv[1 + i] = (char *) args[i];
+ argv[1 + i] = args[i];
if (verbose)
{
char *old_classpath;
unsigned int command_length;
char *command;
- char *argv[4];
+ const char *argv[4];
const char * const *arg;
char *p;
if (!gij_tested)
{
/* Test for presence of gij: "gij --version > /dev/null" */
- char *argv[3];
+ const char *argv[3];
int exitstatus;
argv[0] = "gij";
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. */
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)
{
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";
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
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)
{
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";
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
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)
{
if (!jview_tested)
{
/* Test for presence of jview: "jview -? >nul ; test $? = 1" */
- char *argv[3];
+ const char *argv[3];
int exitstatus;
argv[0] = "jview";
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. */
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)
{
#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.
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;
}
}
-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. */
;
/* 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;
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 */
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,
(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;
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,
#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)
- 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,
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,
/* 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;
/* 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
}
*/
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,
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;
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)
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);
}
}
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);
}
}
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)
!= 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)
*/
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,
*/
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,
*/
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,
* 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,
*
*/
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,
* 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,
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. */
;
/* 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.
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.
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);
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);
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,
#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);
#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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
{
/* 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);
{
/* 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);
{
/* 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);
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);
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);
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__
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__
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);
/* Check the shell_quote_argv function. */
{
- char *argv[1];
+ const char *argv[1];
char *result;
argv[0] = NULL;
result = shell_quote_argv (argv);
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\" \"\\$\"" */
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);