static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
+static int64_t file_seek(struct archive *, void *, int64_t request, int);
static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_seek_callback(a, file_seek);
archive_read_set_close_callback(a, file_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
return (-1);
}
+/*
+ * TODO: Store the offset and use it in the read callback.
+ */
+static int64_t
+file_seek(struct archive *a, void *client_data, int64_t request, int whence)
+{
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+ int64_t r;
+
+ /* We use off_t here because lseek() is declared that way. */
+ /* See above for notes about when off_t is less than 64 bits. */
+ r = lseek(mine->fd, request, whence);
+ if (r >= 0)
+ return r;
+
+ if (errno == ESPIPE) {
+ archive_set_error(a, errno,
+ "A file descriptor(%d) is not seekable(PIPE)", mine->fd);
+ return (ARCHIVE_FAILED);
+ } else {
+ /* If the input is corrupted or truncated, fail. */
+ archive_set_error(a, errno,
+ "Error seeking in a file descriptor(%d)", mine->fd);
+ return (ARCHIVE_FATAL);
+ }
+}
+
static int
file_close(struct archive *a, void *client_data)
{
* The header of the 7z archive files is not encoded.
*/
static void
-test_copy()
+test_copy(int use_open_fd)
{
const char *refname = "test_read_format_7zip_copy.7z";
struct archive_entry *ae;
struct archive *a;
char buff[128];
+ int fd = -1;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_open_filename(a, refname, 10240));
+ if (use_open_fd) {
+ fd = open(refname, O_RDONLY | O_BINARY);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_fd(a, fd, 10240));
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+ }
/* Verify regular file1. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
/* Close the archive. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ if (fd != -1)
+ close(fd);
}
/*
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+DEFINE_TEST(test_read_format_7zip_from_fd)
+{
+ test_copy(1);/* read a 7zip file from a file descriptor. */
+}
+
DEFINE_TEST(test_read_format_7zip_copy)
{
- test_copy();
+ test_copy(0);
test_bcj("test_read_format_7zip_bcj_copy.7z");
test_bcj("test_read_format_7zip_bcj2_copy_1.7z");
test_bcj("test_read_format_7zip_bcj2_copy_2.7z");