/* System-dependent calls for tar.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
+ Free Software Foundation; either version 3, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <system.h>
+#include <setenv.h>
#include "common.h"
#include <rmt.h>
if (archive < 0)
{
int saved_errno = errno;
-
+
if (backup_option)
undo_last_backup ();
errno = saved_errno;
}
}
-static pid_t pid;
+static pid_t global_pid;
static RETSIGTYPE (*pipe_handler) (int sig);
int
xpipe (p);
pipe_handler = signal (SIGPIPE, SIG_IGN);
- pid = xfork ();
+ global_pid = xfork ();
- if (pid != 0)
+ if (global_pid != 0)
{
xclose (p[PREAD]);
return p[PWRITE];
{
int status;
- if (pid < 0)
+ if (global_pid < 0)
return;
signal (SIGPIPE, pipe_handler);
- while (waitpid (pid, &status, 0) == -1)
+ while (waitpid (global_pid, &status, 0) == -1)
if (errno != EINTR)
{
- pid = -1;
+ global_pid = -1;
waitpid_error (to_command_option);
return;
}
{
if (!ignore_command_error_option && WEXITSTATUS (status))
ERROR ((0, 0, _("%lu: Child returned status %d"),
- (unsigned long) pid, WEXITSTATUS (status)));
+ (unsigned long) global_pid, WEXITSTATUS (status)));
}
else if (WIFSIGNALED (status))
{
WARN ((0, 0, _("%lu: Child terminated on signal %d"),
- (unsigned long) pid, WTERMSIG (status)));
+ (unsigned long) global_pid, WTERMSIG (status)));
}
else
ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
- (unsigned long) pid));
+ (unsigned long) global_pid));
- pid = -1;
+ global_pid = -1;
}
int
-sys_exec_info_script (const char *archive_name, int volume_number)
+sys_exec_info_script (const char **archive_name, int volume_number)
{
pid_t pid;
char *argv[4];
char uintbuf[UINTMAX_STRSIZE_BOUND];
+ int p[2];
+
+ xpipe (p);
+ pipe_handler = signal (SIGPIPE, SIG_IGN);
pid = xfork ();
if (pid != 0)
{
- int status;
-
/* Master */
+
+ int rc;
+ int status;
+ char *buf;
+ size_t size = 0;
+ FILE *fp;
+
+ xclose (p[PWRITE]);
+ fp = fdopen (p[PREAD], "r");
+ rc = getline (&buf, &size, fp);
+ fclose (fp);
+
+ if (rc > 0 && buf[rc-1] == '\n')
+ buf[--rc] = 0;
+
while (waitpid (pid, &status, 0) == -1)
if (errno != EINTR)
{
waitpid_error (info_script_option);
return -1;
}
-
+
if (WIFEXITED (status))
- return WEXITSTATUS (status);
-
+ {
+ if (WEXITSTATUS (status) == 0 && rc > 0)
+ *archive_name = buf;
+ else
+ free (buf);
+ return WEXITSTATUS (status);
+ }
+
+ free (buf);
return -1;
}
/* Child */
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
- setenv ("TAR_ARCHIVE", archive_name, 1);
+ setenv ("TAR_ARCHIVE", *archive_name, 1);
setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
setenv ("TAR_FORMAT",
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] = "/bin/sh";
argv[1] = "-c";
argv[2] = (char*) info_script_option;