mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-09-06 00:06:54 +00:00
Pass command line arguments to external commands.
Any option taking a command name as its argument accepts additional arguments as well. * lib/wordsplit.c: New file. * lib/wordsplit.h: New file. * lib/Makefile.am: Add new files. * src/system.c (xexec): New function. (run_decompress_program): Use wordsplit. (sys_child_open_for_compress,sys_exec_command) (sys_exec_info_script) (sys_exec_checkpoint_script): Use xexec to invoke external command. * NEWS: Update. * doc/tar.texi: Update.
This commit is contained in:
+39
-31
@@ -21,6 +21,20 @@
|
||||
#include <priv-set.h>
|
||||
#include <rmt.h>
|
||||
#include <signal.h>
|
||||
#include <wordsplit.h>
|
||||
|
||||
static void
|
||||
xexec (const char *cmd)
|
||||
{
|
||||
struct wordsplit ws;
|
||||
|
||||
ws.ws_env = (const char **) environ;
|
||||
if (wordsplit (cmd, &ws, (WRDSF_DEFFLAGS | WRDSF_ENV) & ~WRDSF_NOVAR))
|
||||
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
|
||||
cmd, wordsplit_strerror (&ws)));
|
||||
execvp (ws.ws_wordv[0], ws.ws_wordv);
|
||||
exec_fatal (cmd);
|
||||
}
|
||||
|
||||
#if MSDOS
|
||||
|
||||
@@ -192,7 +206,7 @@ sys_spawn_shell (void)
|
||||
if (child == 0)
|
||||
{
|
||||
priv_set_restore_linkdir ();
|
||||
execlp (shell, "-sh", "-i", (char *) 0);
|
||||
execlp (shell, "-sh", "-i", NULL);
|
||||
exec_fatal (shell);
|
||||
}
|
||||
else
|
||||
@@ -315,7 +329,7 @@ sys_child_open_for_compress (void)
|
||||
int child_pipe[2];
|
||||
pid_t grandchild_pid;
|
||||
pid_t child_pid;
|
||||
|
||||
|
||||
xpipe (parent_pipe);
|
||||
child_pid = xfork ();
|
||||
|
||||
@@ -363,8 +377,7 @@ sys_child_open_for_compress (void)
|
||||
xdup2 (archive, STDOUT_FILENO);
|
||||
}
|
||||
priv_set_restore_linkdir ();
|
||||
execlp (use_compress_program_option, use_compress_program_option, NULL);
|
||||
exec_fatal (use_compress_program_option);
|
||||
xexec (use_compress_program_option);
|
||||
}
|
||||
|
||||
/* We do need a grandchild tar. */
|
||||
@@ -381,9 +394,7 @@ sys_child_open_for_compress (void)
|
||||
xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
|
||||
xclose (child_pipe[PREAD]);
|
||||
priv_set_restore_linkdir ();
|
||||
execlp (use_compress_program_option, use_compress_program_option,
|
||||
(char *) 0);
|
||||
exec_fatal (use_compress_program_option);
|
||||
xexec (use_compress_program_option);
|
||||
}
|
||||
|
||||
/* The child tar is still here! */
|
||||
@@ -458,7 +469,12 @@ run_decompress_program (void)
|
||||
{
|
||||
int i;
|
||||
const char *p, *prog = NULL;
|
||||
struct wordsplit ws;
|
||||
int wsflags = (WRDSF_DEFFLAGS | WRDSF_ENV | WRDSF_DOOFFS) & ~WRDSF_NOVAR;
|
||||
|
||||
ws.ws_env = (const char **) environ;
|
||||
ws.ws_offs = 1;
|
||||
|
||||
for (p = first_decompress_program (&i); p; p = next_decompress_program (&i))
|
||||
{
|
||||
if (prog)
|
||||
@@ -468,8 +484,16 @@ run_decompress_program (void)
|
||||
WARNOPT (WARN_DECOMPRESS_PROGRAM,
|
||||
(0, 0, _("trying %s"), p));
|
||||
}
|
||||
prog = p;
|
||||
execlp (p, p, "-d", NULL);
|
||||
if (wordsplit (p, &ws, wsflags))
|
||||
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
|
||||
p, wordsplit_strerror (&ws)));
|
||||
wsflags |= WRDSF_REUSE;
|
||||
memmove(ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
|
||||
sizeof(ws.ws_wordv[0])*ws.ws_wordc);
|
||||
ws.ws_wordv[ws.ws_wordc] = "-d";
|
||||
prog = p;
|
||||
execvp (ws.ws_wordv[0], ws.ws_wordv);
|
||||
ws.ws_wordv[ws.ws_wordc] = NULL;
|
||||
}
|
||||
if (!prog)
|
||||
FATAL_ERROR ((0, 0, _("unable to run decompression program")));
|
||||
@@ -703,7 +727,7 @@ sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
|
||||
{
|
||||
int p[2];
|
||||
char *argv[4];
|
||||
|
||||
|
||||
xpipe (p);
|
||||
pipe_handler = signal (SIGPIPE, SIG_IGN);
|
||||
global_pid = xfork ();
|
||||
@@ -720,15 +744,8 @@ sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
|
||||
|
||||
stat_to_env (file_name, typechar, st);
|
||||
|
||||
argv[0] = (char *) "/bin/sh";
|
||||
argv[1] = (char *) "-c";
|
||||
argv[2] = to_command_option;
|
||||
argv[3] = NULL;
|
||||
|
||||
priv_set_restore_linkdir ();
|
||||
execv ("/bin/sh", argv);
|
||||
|
||||
exec_fatal (file_name);
|
||||
xexec (to_command_option);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -832,18 +849,11 @@ sys_exec_info_script (const char **archive_name, int volume_number)
|
||||
archive_format_string (current_format == DEFAULT_FORMAT ?
|
||||
archive_format : current_format), 1);
|
||||
setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
|
||||
|
||||
|
||||
xclose (p[PREAD]);
|
||||
|
||||
argv[0] = (char *) "/bin/sh";
|
||||
argv[1] = (char *) "-c";
|
||||
argv[2] = (char *) info_script_option;
|
||||
argv[3] = NULL;
|
||||
|
||||
priv_set_restore_linkdir ();
|
||||
execv (argv[0], argv);
|
||||
|
||||
exec_fatal (info_script_option);
|
||||
xexec (info_script_option);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -854,7 +864,7 @@ sys_exec_checkpoint_script (const char *script_name,
|
||||
pid_t pid;
|
||||
char *argv[4];
|
||||
char uintbuf[UINTMAX_STRSIZE_BOUND];
|
||||
|
||||
|
||||
pid = xfork ();
|
||||
|
||||
if (pid != 0)
|
||||
@@ -889,9 +899,7 @@ sys_exec_checkpoint_script (const char *script_name,
|
||||
argv[3] = NULL;
|
||||
|
||||
priv_set_restore_linkdir ();
|
||||
execv (argv[0], argv);
|
||||
|
||||
exec_fatal (script_name);
|
||||
xexec (script_name);
|
||||
}
|
||||
|
||||
#endif /* not MSDOS */
|
||||
|
||||
Reference in New Issue
Block a user