1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Add hook for a client-provided progress callback to be invoked

during lengthy extract operations.
This commit is contained in:
Tim Kientzle 2004-05-13 06:01:14 +00:00
parent 9cbb335cfd
commit 199984b3b2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129171
6 changed files with 34 additions and 2 deletions

View File

@ -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 *);

View File

@ -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 *);

View File

@ -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;

View File

@ -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.

View File

@ -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);
}

View File

@ -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;
}