void sys_exec_checkpoint_script (const char *script_name, const char *archive_name, int checkpoint_number) { pid_t pid; char *argv[4]; char uintbuf[UINTMAX_STRSIZE_BOUND]; pid = xfork (); if (pid != 0) { /* Master */ int status; while (waitpid (pid, &status, 0) == -1) if (errno != EINTR) { waitpid_error (script_name); break; } return; } /* Child */ setenv ("TAR_VERSION", PACKAGE_VERSION, 1); setenv ("TAR_ARCHIVE", archive_name, 1); setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1); setenv ("TAR_BLOCKING_FACTOR", STRINGIFY_BIGINT (blocking_factor, 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); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = (char*) script_name; argv[3] = NULL; execv (argv[0], argv); exec_fatal (script_name); }
static void stat_to_env (char *name, char type, struct tar_stat_info *st) { str_to_env ("TAR_VERSION", PACKAGE_VERSION); str_to_env ("TAR_ARCHIVE", *archive_name_cursor); dec_to_env ("TAR_VOLUME", archive_name_cursor - archive_name_array + 1); dec_to_env ("TAR_BLOCKING_FACTOR", blocking_factor); str_to_env ("TAR_FORMAT", archive_format_string (current_format == DEFAULT_FORMAT ? archive_format : current_format)); chr_to_env ("TAR_FILETYPE", type); oct_to_env ("TAR_MODE", st->stat.st_mode); str_to_env ("TAR_FILENAME", name); str_to_env ("TAR_REALNAME", st->file_name); str_to_env ("TAR_UNAME", st->uname); str_to_env ("TAR_GNAME", st->gname); time_to_env ("TAR_ATIME", st->atime); time_to_env ("TAR_MTIME", st->mtime); time_to_env ("TAR_CTIME", st->ctime); dec_to_env ("TAR_SIZE", st->stat.st_size); dec_to_env ("TAR_UID", st->stat.st_uid); dec_to_env ("TAR_GID", st->stat.st_gid); switch (type) { case 'b': case 'c': dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev)); dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev)); unsetenv ("TAR_LINKNAME"); break; case 'l': case 'h': unsetenv ("TAR_MINOR"); unsetenv ("TAR_MAJOR"); str_to_env ("TAR_LINKNAME", st->link_name); break; default: unsetenv ("TAR_MINOR"); unsetenv ("TAR_MAJOR"); unsetenv ("TAR_LINKNAME"); break; } }
int 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]; static RETSIGTYPE (*saved_handler) (int sig); xpipe (p); saved_handler = signal (SIGPIPE, SIG_IGN); pid = xfork (); if (pid != 0) { /* Master */ int rc; int status; char *buf = NULL; 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) { signal (SIGPIPE, saved_handler); waitpid_error (info_script_option); return -1; } signal (SIGPIPE, saved_handler); if (WIFEXITED (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_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1); setenv ("TAR_BLOCKING_FACTOR", STRINGIFY_BIGINT (blocking_factor, 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; argv[3] = NULL; execv (argv[0], argv); exec_fatal (info_script_option); }