mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 19:08:58 +00:00
Refactor the siginfo/sigusr1 handling. The read/write reporting
is sufficiently different that it was simpler to just put separate reporting functions into read.c and write.c rather than try to have a single all-purpose reporting function. Switch to a custom function for converting int64_t to a string; in the portable version, this saves a lot of configuration headaches trying to decipher the platform printf().
This commit is contained in:
parent
a48279bb03
commit
12d4db7c3f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=203568
@ -9,7 +9,6 @@ SRCS= bsdtar.c \
|
||||
getdate.c \
|
||||
matching.c \
|
||||
read.c \
|
||||
siginfo.c \
|
||||
subst.c \
|
||||
tree.c \
|
||||
util.c \
|
||||
|
@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@ -82,7 +85,32 @@ __FBSDID("$FreeBSD$");
|
||||
#define _PATH_DEFTAPE "/dev/tape"
|
||||
#endif
|
||||
|
||||
/* External function to parse a date/time string (from getdate.y) */
|
||||
#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
|
||||
static volatile int siginfo_occurred;
|
||||
|
||||
static void
|
||||
siginfo_handler(int sig)
|
||||
{
|
||||
(void)sig; /* UNUSED */
|
||||
siginfo_occurred = 1;
|
||||
}
|
||||
|
||||
int
|
||||
need_report(void)
|
||||
{
|
||||
int r = siginfo_occurred;
|
||||
siginfo_occurred = 0;
|
||||
return (r);
|
||||
}
|
||||
#else
|
||||
int
|
||||
need_report(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* External function to parse a date/time string */
|
||||
time_t get_date(time_t, const char *);
|
||||
|
||||
static void long_help(void);
|
||||
@ -114,11 +142,23 @@ main(int argc, char **argv)
|
||||
memset(bsdtar, 0, sizeof(*bsdtar));
|
||||
bsdtar->fd = -1; /* Mark as "unused" */
|
||||
option_o = 0;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure open() function will be used with a binary mode. */
|
||||
/* on cygwin, we need something similar, but instead link against */
|
||||
/* a special startup object, binmode.o */
|
||||
_set_fmode(_O_BINARY);
|
||||
|
||||
#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
|
||||
{ /* Catch SIGINFO and SIGUSR1, if they exist. */
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = siginfo_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
#ifdef SIGINFO
|
||||
if (sigaction(SIGINFO, &sa, NULL))
|
||||
bsdtar_errc(1, errno, "sigaction(SIGINFO) failed");
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
/* ... and treat SIGUSR1 the same way as SIGINFO. */
|
||||
if (sigaction(SIGUSR1, &sa, NULL))
|
||||
bsdtar_errc(1, errno, "sigaction(SIGUSR1) failed");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Need bsdtar_progname before calling bsdtar_warnc. */
|
||||
|
@ -142,16 +142,13 @@ int exclude_from_file(struct bsdtar *, const char *pathname);
|
||||
int excluded(struct bsdtar *, const char *pathname);
|
||||
int include(struct bsdtar *, const char *pattern);
|
||||
int include_from_file(struct bsdtar *, const char *pathname);
|
||||
int need_report(void);
|
||||
int pathcmp(const char *a, const char *b);
|
||||
int process_lines(struct bsdtar *bsdtar, const char *pathname,
|
||||
int (*process)(struct bsdtar *, const char *));
|
||||
void safe_fprintf(FILE *, const char *fmt, ...);
|
||||
void set_chdir(struct bsdtar *, const char *newdir);
|
||||
void siginfo_init(struct bsdtar *);
|
||||
void siginfo_setinfo(struct bsdtar *, const char * oper,
|
||||
const char * path, int64_t size);
|
||||
void siginfo_printinfo(struct bsdtar *, off_t progress);
|
||||
void siginfo_done(struct bsdtar *);
|
||||
const char *tar_i64toa(int64_t);
|
||||
void tar_mode_c(struct bsdtar *bsdtar);
|
||||
void tar_mode_r(struct bsdtar *bsdtar);
|
||||
void tar_mode_t(struct bsdtar *bsdtar);
|
||||
|
@ -70,6 +70,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include "bsdtar.h"
|
||||
#include "err.h"
|
||||
|
||||
struct progress_data {
|
||||
struct bsdtar *bsdtar;
|
||||
struct archive *archive;
|
||||
struct archive_entry *entry;
|
||||
};
|
||||
|
||||
static void list_item_verbose(struct bsdtar *, FILE *,
|
||||
struct archive_entry *);
|
||||
static void read_archive(struct bsdtar *bsdtar, char mode);
|
||||
@ -84,22 +90,40 @@ tar_mode_t(struct bsdtar *bsdtar)
|
||||
void
|
||||
tar_mode_x(struct bsdtar *bsdtar)
|
||||
{
|
||||
/* We want to catch SIGINFO and SIGUSR1. */
|
||||
siginfo_init(bsdtar);
|
||||
|
||||
read_archive(bsdtar, 'x');
|
||||
|
||||
unmatched_inclusions_warn(bsdtar, "Not found in archive");
|
||||
/* Restore old SIGINFO + SIGUSR1 handlers. */
|
||||
siginfo_done(bsdtar);
|
||||
}
|
||||
|
||||
static void
|
||||
progress_func(void * cookie)
|
||||
progress_func(void *cookie)
|
||||
{
|
||||
struct bsdtar * bsdtar = cookie;
|
||||
struct progress_data *progress_data = cookie;
|
||||
struct bsdtar *bsdtar = progress_data->bsdtar;
|
||||
struct archive *a = progress_data->archive;
|
||||
struct archive_entry *entry = progress_data->entry;
|
||||
uint64_t comp, uncomp;
|
||||
|
||||
siginfo_printinfo(bsdtar, 0);
|
||||
if (!need_report())
|
||||
return;
|
||||
|
||||
if (bsdtar->verbose)
|
||||
fprintf(stderr, "\n");
|
||||
if (a != NULL) {
|
||||
comp = archive_position_compressed(a);
|
||||
uncomp = archive_position_uncompressed(a);
|
||||
fprintf(stderr,
|
||||
"In: %s bytes, compression %d%%;",
|
||||
tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp));
|
||||
fprintf(stderr, " Out: %d files, %s bytes\n",
|
||||
archive_file_count(a), tar_i64toa(uncomp));
|
||||
}
|
||||
if (entry != NULL) {
|
||||
safe_fprintf(stderr, "Current: %s",
|
||||
archive_entry_pathname(entry));
|
||||
fprintf(stderr, " (%s bytes)\n",
|
||||
tar_i64toa(archive_entry_size(entry)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -108,6 +132,7 @@ progress_func(void * cookie)
|
||||
static void
|
||||
read_archive(struct bsdtar *bsdtar, char mode)
|
||||
{
|
||||
struct progress_data progress_data;
|
||||
FILE *out;
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
@ -140,8 +165,10 @@ read_archive(struct bsdtar *bsdtar, char mode)
|
||||
|
||||
if (mode == 'x') {
|
||||
/* Set an extract callback so that we can handle SIGINFO. */
|
||||
progress_data.bsdtar = bsdtar;
|
||||
progress_data.archive = a;
|
||||
archive_read_extract_set_progress_callback(a, progress_func,
|
||||
bsdtar);
|
||||
&progress_data);
|
||||
}
|
||||
|
||||
if (mode == 'x' && bsdtar->option_chroot) {
|
||||
@ -161,6 +188,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
|
||||
break;
|
||||
|
||||
r = archive_read_next_header(a, &entry);
|
||||
progress_data.entry = entry;
|
||||
if (r == ARCHIVE_EOF)
|
||||
break;
|
||||
if (r < ARCHIVE_OK)
|
||||
@ -268,10 +296,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* Tell the SIGINFO-handler code what we're doing. */
|
||||
siginfo_setinfo(bsdtar, "extracting",
|
||||
archive_entry_pathname(entry), 0);
|
||||
siginfo_printinfo(bsdtar, 0);
|
||||
// TODO siginfo_printinfo(bsdtar, 0);
|
||||
|
||||
if (bsdtar->option_stdout)
|
||||
r = archive_read_data_into_fd(a, 1);
|
||||
|
@ -1,152 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2008 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "bsdtar_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsdtar.h"
|
||||
#include "err.h"
|
||||
|
||||
/* Is there a pending SIGINFO or SIGUSR1? */
|
||||
static volatile sig_atomic_t siginfo_received = 0;
|
||||
|
||||
struct siginfo_data {
|
||||
/* What sort of operation are we doing? */
|
||||
char * oper;
|
||||
|
||||
/* What path are we handling? */
|
||||
char * path;
|
||||
|
||||
/* How large is the archive entry? */
|
||||
int64_t size;
|
||||
|
||||
/* Old signal handlers. */
|
||||
#ifdef SIGINFO
|
||||
void (*siginfo_old)(int);
|
||||
#endif
|
||||
void (*sigusr1_old)(int);
|
||||
};
|
||||
|
||||
static void siginfo_handler(int sig);
|
||||
|
||||
/* Handler for SIGINFO / SIGUSR1. */
|
||||
static void
|
||||
siginfo_handler(int sig)
|
||||
{
|
||||
|
||||
(void)sig; /* UNUSED */
|
||||
|
||||
/* Record that SIGINFO or SIGUSR1 has been received. */
|
||||
siginfo_received = 1;
|
||||
}
|
||||
|
||||
void
|
||||
siginfo_init(struct bsdtar *bsdtar)
|
||||
{
|
||||
|
||||
/* Allocate space for internal structure. */
|
||||
if ((bsdtar->siginfo = malloc(sizeof(struct siginfo_data))) == NULL)
|
||||
bsdtar_errc(1, errno, "malloc failed");
|
||||
|
||||
/* Set the strings to NULL so that free() is safe. */
|
||||
bsdtar->siginfo->path = bsdtar->siginfo->oper = NULL;
|
||||
|
||||
#ifdef SIGINFO
|
||||
/* We want to catch SIGINFO, if it exists. */
|
||||
bsdtar->siginfo->siginfo_old = signal(SIGINFO, siginfo_handler);
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
/* ... and treat SIGUSR1 the same way as SIGINFO. */
|
||||
bsdtar->siginfo->sigusr1_old = signal(SIGUSR1, siginfo_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
siginfo_setinfo(struct bsdtar *bsdtar, const char * oper, const char * path,
|
||||
int64_t size)
|
||||
{
|
||||
|
||||
/* Free old operation and path strings. */
|
||||
free(bsdtar->siginfo->oper);
|
||||
free(bsdtar->siginfo->path);
|
||||
|
||||
/* Duplicate strings and store entry size. */
|
||||
if ((bsdtar->siginfo->oper = strdup(oper)) == NULL)
|
||||
bsdtar_errc(1, errno, "Cannot strdup");
|
||||
if ((bsdtar->siginfo->path = strdup(path)) == NULL)
|
||||
bsdtar_errc(1, errno, "Cannot strdup");
|
||||
bsdtar->siginfo->size = size;
|
||||
}
|
||||
|
||||
void
|
||||
siginfo_printinfo(struct bsdtar *bsdtar, off_t progress)
|
||||
{
|
||||
|
||||
/* If there's a signal to handle and we know what we're doing... */
|
||||
if ((siginfo_received == 1) &&
|
||||
(bsdtar->siginfo->path != NULL) &&
|
||||
(bsdtar->siginfo->oper != NULL)) {
|
||||
if (bsdtar->verbose)
|
||||
fprintf(stderr, "\n");
|
||||
if (bsdtar->siginfo->size > 0) {
|
||||
safe_fprintf(stderr, "%s %s (%ju / %" PRId64 ")",
|
||||
bsdtar->siginfo->oper, bsdtar->siginfo->path,
|
||||
(uintmax_t)progress, bsdtar->siginfo->size);
|
||||
} else {
|
||||
safe_fprintf(stderr, "%s %s",
|
||||
bsdtar->siginfo->oper, bsdtar->siginfo->path);
|
||||
}
|
||||
if (!bsdtar->verbose)
|
||||
fprintf(stderr, "\n");
|
||||
siginfo_received = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
siginfo_done(struct bsdtar *bsdtar)
|
||||
{
|
||||
|
||||
#ifdef SIGINFO
|
||||
/* Restore old SIGINFO handler. */
|
||||
signal(SIGINFO, bsdtar->siginfo->siginfo_old);
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
/* And the old SIGUSR1 handler, too. */
|
||||
signal(SIGUSR1, bsdtar->siginfo->sigusr1_old);
|
||||
#endif
|
||||
|
||||
/* Free strings. */
|
||||
free(bsdtar->siginfo->path);
|
||||
free(bsdtar->siginfo->oper);
|
||||
|
||||
/* Free internal data structure. */
|
||||
free(bsdtar->siginfo);
|
||||
}
|
@ -558,6 +558,28 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* It would be nice to just use printf() for formatting large numbers,
|
||||
* but the compatibility problems are quite a headache. Hence the
|
||||
* following simple utility function.
|
||||
*/
|
||||
const char *
|
||||
tar_i64toa(int64_t n0)
|
||||
{
|
||||
static char buff[24];
|
||||
int64_t n = n0 < 0 ? -n0 : n0;
|
||||
char *p = buff + sizeof(buff);
|
||||
|
||||
*--p = '\0';
|
||||
do {
|
||||
*--p = '0' + (int)(n % 10);
|
||||
n /= 10;
|
||||
} while (n > 0);
|
||||
if (n0 < 0)
|
||||
*--p = '-';
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like strcmp(), but try to be a little more aware of the fact that
|
||||
* we're comparing two paths. Right now, it just handles leading
|
||||
|
@ -127,10 +127,12 @@ static void archive_names_from_file(struct bsdtar *bsdtar,
|
||||
struct archive *a);
|
||||
static int archive_names_from_file_helper(struct bsdtar *bsdtar,
|
||||
const char *line);
|
||||
static int copy_file_data(struct bsdtar *bsdtar,
|
||||
struct archive *a, struct archive *ina);
|
||||
static int copy_file_data(struct bsdtar *, struct archive *a,
|
||||
struct archive *ina, struct archive_entry *);
|
||||
static int new_enough(struct bsdtar *, const char *path,
|
||||
const struct stat *);
|
||||
static void report_write(struct bsdtar *, struct archive *,
|
||||
struct archive_entry *, int64_t progress);
|
||||
static void test_for_append(struct bsdtar *);
|
||||
static void write_archive(struct archive *, struct bsdtar *);
|
||||
static void write_entry_backend(struct bsdtar *, struct archive *,
|
||||
@ -414,9 +416,6 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
|
||||
const char *arg;
|
||||
struct archive_entry *entry, *sparse_entry;
|
||||
|
||||
/* We want to catch SIGINFO and SIGUSR1. */
|
||||
siginfo_init(bsdtar);
|
||||
|
||||
/* Allocate a buffer for file data. */
|
||||
if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
|
||||
bsdtar_errc(1, 0, "cannot allocate memory");
|
||||
@ -488,14 +487,11 @@ cleanup:
|
||||
bsdtar->diskreader = NULL;
|
||||
|
||||
if (bsdtar->option_totals) {
|
||||
fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
|
||||
(BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
|
||||
fprintf(stderr, "Total bytes written: %s\n",
|
||||
tar_i64toa(archive_position_compressed(a)));
|
||||
}
|
||||
|
||||
archive_write_finish(a);
|
||||
|
||||
/* Restore old SIGINFO + SIGUSR1 handlers. */
|
||||
siginfo_done(bsdtar);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -591,10 +587,8 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
|
||||
if (bsdtar->verbose)
|
||||
safe_fprintf(stderr, "a %s",
|
||||
archive_entry_pathname(in_entry));
|
||||
siginfo_setinfo(bsdtar, "copying",
|
||||
archive_entry_pathname(in_entry),
|
||||
archive_entry_size(in_entry));
|
||||
siginfo_printinfo(bsdtar, 0);
|
||||
if (need_report())
|
||||
report_write(bsdtar, a, in_entry, 0);
|
||||
|
||||
e = archive_write_header(a, in_entry);
|
||||
if (e != ARCHIVE_OK) {
|
||||
@ -611,7 +605,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
|
||||
if (e >= ARCHIVE_WARN) {
|
||||
if (archive_entry_size(in_entry) == 0)
|
||||
archive_read_data_skip(ina);
|
||||
else if (copy_file_data(bsdtar, a, ina))
|
||||
else if (copy_file_data(bsdtar, a, ina, in_entry))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -625,7 +619,8 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
|
||||
|
||||
/* Helper function to copy data between archives. */
|
||||
static int
|
||||
copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
|
||||
copy_file_data(struct bsdtar *bsdtar, struct archive *a,
|
||||
struct archive *ina, struct archive_entry *entry)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
ssize_t bytes_written;
|
||||
@ -633,7 +628,8 @@ copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
|
||||
|
||||
bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
|
||||
while (bytes_read > 0) {
|
||||
siginfo_printinfo(bsdtar, progress);
|
||||
if (need_report())
|
||||
report_write(bsdtar, a, entry, progress);
|
||||
|
||||
bytes_written = archive_write_data(a, bsdtar->buff,
|
||||
bytes_read);
|
||||
@ -839,14 +835,8 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
|
||||
if (!S_ISREG(st->st_mode))
|
||||
archive_entry_set_size(entry, 0);
|
||||
|
||||
/* Record what we're doing, for SIGINFO / SIGUSR1. */
|
||||
siginfo_setinfo(bsdtar, "adding",
|
||||
archive_entry_pathname(entry), archive_entry_size(entry));
|
||||
archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry);
|
||||
|
||||
/* Handle SIGINFO / SIGUSR1 request if one was made. */
|
||||
siginfo_printinfo(bsdtar, 0);
|
||||
|
||||
while (entry != NULL) {
|
||||
write_entry_backend(bsdtar, a, entry);
|
||||
archive_entry_free(entry);
|
||||
@ -916,6 +906,28 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void
|
||||
report_write(struct bsdtar *bsdtar, struct archive *a,
|
||||
struct archive_entry *entry, int64_t progress)
|
||||
{
|
||||
uint64_t comp, uncomp;
|
||||
if (bsdtar->verbose)
|
||||
fprintf(stderr, "\n");
|
||||
comp = archive_position_compressed(a);
|
||||
uncomp = archive_position_uncompressed(a);
|
||||
fprintf(stderr, "In: %d files, %s bytes;",
|
||||
archive_file_count(a), tar_i64toa(uncomp));
|
||||
fprintf(stderr,
|
||||
" Out: %s bytes, compression %d%%\n",
|
||||
tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp));
|
||||
/* Can't have two calls to tar_i64toa() pending, so split the output. */
|
||||
safe_fprintf(stderr, "Current: %s (%s",
|
||||
archive_entry_pathname(entry),
|
||||
tar_i64toa(progress));
|
||||
fprintf(stderr, "/%s bytes)\n",
|
||||
tar_i64toa(archive_entry_size(entry)));
|
||||
}
|
||||
|
||||
|
||||
/* Helper function to copy file to archive. */
|
||||
static int
|
||||
@ -928,7 +940,8 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a,
|
||||
|
||||
bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
|
||||
while (bytes_read > 0) {
|
||||
siginfo_printinfo(bsdtar, progress);
|
||||
if (need_report())
|
||||
report_write(bsdtar, a, entry, progress);
|
||||
|
||||
bytes_written = archive_write_data(a, bsdtar->buff,
|
||||
bytes_read);
|
||||
|
Loading…
Reference in New Issue
Block a user