summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libarchive/archive.h2
-rw-r--r--lib/libarchive/archive.h.in2
-rw-r--r--lib/libarchive/archive_private.h2
-rw-r--r--lib/libarchive/archive_read.312
-rw-r--r--lib/libarchive/archive_read_data_into_fd.c10
-rw-r--r--lib/libarchive/archive_read_extract.c8
6 files changed, 34 insertions, 2 deletions
diff --git a/lib/libarchive/archive.h b/lib/libarchive/archive.h
index f0489eb..b8f03a3 100644
--- a/lib/libarchive/archive.h
+++ b/lib/libarchive/archive.h
@@ -200,6 +200,8 @@ ssize_t archive_read_data_into_fd(struct archive *, int fd);
int archive_read_extract(struct archive *, struct archive_entry *,
int flags);
+void archive_read_extract_set_progress_callback(struct archive *,
+ void (*_progress_func)(void *), void *_user_data);
/* Close the file, release any resources, and destroy the object. */
void archive_read_finish(struct archive *);
diff --git a/lib/libarchive/archive.h.in b/lib/libarchive/archive.h.in
index f0489eb..b8f03a3 100644
--- a/lib/libarchive/archive.h.in
+++ b/lib/libarchive/archive.h.in
@@ -200,6 +200,8 @@ ssize_t archive_read_data_into_fd(struct archive *, int fd);
int archive_read_extract(struct archive *, struct archive_entry *,
int flags);
+void archive_read_extract_set_progress_callback(struct archive *,
+ void (*_progress_func)(void *), void *_user_data);
/* Close the file, release any resources, and destroy the object. */
void archive_read_finish(struct archive *);
diff --git a/lib/libarchive/archive_private.h b/lib/libarchive/archive_private.h
index f7f4158..f3d3b87 100644
--- a/lib/libarchive/archive_private.h
+++ b/lib/libarchive/archive_private.h
@@ -192,6 +192,8 @@ struct archive {
*/
struct archive_string extract_mkdirpath;
struct archive_extract_dir_entry *archive_extract_dir_list;
+ void (*extract_progress)(void *);
+ void *extract_progress_user_data;
void (*cleanup_archive_extract)(struct archive *);
int archive_error_number;
diff --git a/lib/libarchive/archive_read.3 b/lib/libarchive/archive_read.3
index 28131cd..421b3f6 100644
--- a/lib/libarchive/archive_read.3
+++ b/lib/libarchive/archive_read.3
@@ -47,6 +47,7 @@
.Nm archive_read_data_into_buffer ,
.Nm archive_read_data_into_file ,
.Nm archive_read_extract ,
+.Nm archive_read_extract_set_progress_callback ,
.Nm archive_read_finish
.Nd functions for reading tar archives
.Sh SYNOPSIS
@@ -90,6 +91,8 @@
.Ft int
.Fn archive_read_extract "struct archive *" "int flags"
.Ft void
+.Fn archive_read_extract_set_progress_callback "struct archive *" "void (*func)(void *)" "void *user_data"
+.Ft void
.Fn archive_read_finish "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for reading streaming archives.
@@ -202,6 +205,15 @@ By default, existing files are truncated and rewritten, but
the file is not recreated.
In particular, the default behavior does not break existing hard links.
.El
+.It Fn archive_read_extract_set_progress_callback
+Sets a pointer to a user-defined callback that can be used
+for updating progress displays during extraction.
+The progress function will be invoked during the extraction of large
+regular files.
+The progress function will be invoked with the pointer provided to this call.
+Generally, the data pointed to should include a reference to the archive
+object and the archive_entry object so that various statistics
+can be retrieved for the progress display.
.It Fn archive_read_finish
Complete the archive, invoke the close callback, and release
all resources.
diff --git a/lib/libarchive/archive_read_data_into_fd.c b/lib/libarchive/archive_read_data_into_fd.c
index 71fdedc..9bdad4d 100644
--- a/lib/libarchive/archive_read_data_into_fd.c
+++ b/lib/libarchive/archive_read_data_into_fd.c
@@ -44,12 +44,16 @@ archive_read_data_into_fd(struct archive *a, int fd)
total_written = 0;
while (a->entry_bytes_remaining > 0) {
- bytes_read = (a->compression_read_ahead)(a, &buff,
- a->entry_bytes_remaining);
+ /* Remember: '1' here is minimum, not maximum. */
+ /* Read-ahead function will return as much as is convenient. */
+ bytes_read = (a->compression_read_ahead)(a, &buff, 1);
if (bytes_read < 0)
return (-1);
if (bytes_read > a->entry_bytes_remaining)
bytes_read = (ssize_t)a->entry_bytes_remaining;
+ /* Don't copy more than 1 megabyte at a time. */
+ if (bytes_read > (1024*1024))
+ bytes_read = 1024*1024;
bytes_written = write(fd, buff, bytes_read);
if (bytes_written < 0)
@@ -57,6 +61,8 @@ archive_read_data_into_fd(struct archive *a, int fd)
(a->compression_read_consume)(a, bytes_written);
total_written += bytes_written;
a->entry_bytes_remaining -= bytes_written;
+ if (a->extract_progress != NULL)
+ (*a->extract_progress)(a->extract_progress_user_data);
}
return (total_written);
}
diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c
index fa3974f..0d49f6f 100644
--- a/lib/libarchive/archive_read_extract.c
+++ b/lib/libarchive/archive_read_extract.c
@@ -1078,3 +1078,11 @@ lookup_uid(struct archive *a, const char *uname, uid_t uid)
}
return (uid);
}
+
+void
+archive_read_extract_set_progress_callback(struct archive *a,
+ void (*progress_func)(void *), void *user_data)
+{
+ a->extract_progress = progress_func;
+ a->extract_progress_user_data = user_data;
+}
OpenPOWER on IntegriCloud