Skip to content

Fixes #138 #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ futures-io = { version = "0.3.5", optional = true }
futures-util = { version = "0.3.5", features = ["sink", "io"], optional = true }
futures-executor = { version = "0.3.5", optional = true }
blocking = { version = "1.0.0", optional = true }
tokio = { version = "1.0.0", features = ["rt-multi-thread", "macros", "fs", "net"], optional = true }
tokio-util = { version = "0.7.0", features = ["compat"], optional = true }
tokio = { version = "=1.38", features = ["rt-multi-thread", "macros", "fs", "net"], optional = true }
tokio-util = { version = "=0.7.11", features = ["compat"], optional = true }
libc = "0.2.86"

[features]
Expand Down
77 changes: 40 additions & 37 deletions scripts/generate-ffi
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,54 @@ EOF

bindgen \
\
--size_t-is-usize \
--rust-target "1.65.0" \
\
--raw-line "#![allow(non_camel_case_types)]" \
--raw-line "#[cfg(not(target_os = \"windows\"))]" \
--raw-line "use libc::stat;" \
--raw-line "#[cfg(target_os = \"windows\")]" \
--raw-line "use crate::stat;" \
--raw-line "pub const ARCHIVE_EOF: i32 = 1;" \
--raw-line "pub const ARCHIVE_OK: i32 = 0;" \
\
--whitelist-var "ARCHIVE_WARN" \
--allowlist-var "ARCHIVE_WARN" \
\
--whitelist-var "ARCHIVE_EXTRACT_TIME" \
--whitelist-var "ARCHIVE_EXTRACT_PERM" \
--whitelist-var "ARCHIVE_EXTRACT_ACL" \
--whitelist-var "ARCHIVE_EXTRACT_FFLAGS" \
--whitelist-var "ARCHIVE_EXTRACT_OWNER" \
--whitelist-var "ARCHIVE_EXTRACT_FFLAGS" \
--whitelist-var "ARCHIVE_EXTRACT_XATTR" \
--whitelist-function "archive_read_new" \
--whitelist-function "archive_read_set_seek_callback" \
--whitelist-function "archive_read_support_filter_all" \
--whitelist-function "archive_read_support_format_all" \
--whitelist-function "archive_read_support_format_raw" \
--whitelist-function "archive_read_close" \
--whitelist-function "archive_read_free" \
--whitelist-function "archive_read_data_block" \
--whitelist-function "archive_read_next_header" \
--whitelist-function "archive_read_open" \
--whitelist-function "archive_write_disk_new" \
--whitelist-function "archive_write_disk_set_options" \
--whitelist-function "archive_write_disk_set_standard_lookup" \
--whitelist-function "archive_write_header" \
--whitelist-function "archive_write_finish_entry" \
--whitelist-function "archive_write_data_block" \
--whitelist-function "archive_write_close" \
--whitelist-function "archive_write_free" \
--whitelist-function "archive_entry_pathname" \
--whitelist-function "archive_entry_free" \
--whitelist-function "archive_entry_set_pathname" \
--whitelist-function "archive_entry_set_hardlink" \
--whitelist-function "archive_entry_hardlink" \
--allowlist-var "ARCHIVE_EXTRACT_TIME" \
--allowlist-var "ARCHIVE_EXTRACT_PERM" \
--allowlist-var "ARCHIVE_EXTRACT_ACL" \
--allowlist-var "ARCHIVE_EXTRACT_FFLAGS" \
--allowlist-var "ARCHIVE_EXTRACT_OWNER" \
--allowlist-var "ARCHIVE_EXTRACT_FFLAGS" \
--allowlist-var "ARCHIVE_EXTRACT_XATTR" \
--allowlist-function "archive_read_new" \
--allowlist-function "archive_read_set_seek_callback" \
--allowlist-function "archive_read_support_filter_all" \
--allowlist-function "archive_read_support_format_all" \
--allowlist-function "archive_read_support_format_raw" \
--allowlist-function "archive_read_close" \
--allowlist-function "archive_read_free" \
--allowlist-function "archive_read_data_block" \
--allowlist-function "archive_read_next_header" \
--allowlist-function "archive_read_open" \
--allowlist-function "archive_write_disk_new" \
--allowlist-function "archive_write_disk_set_options" \
--allowlist-function "archive_write_disk_set_standard_lookup" \
--allowlist-function "archive_write_header" \
--allowlist-function "archive_write_finish_entry" \
--allowlist-function "archive_write_data_block" \
--allowlist-function "archive_write_close" \
--allowlist-function "archive_write_free" \
--allowlist-function "archive_entry_pathname" \
--allowlist-function "archive_entry_free" \
--allowlist-function "archive_entry_set_pathname" \
--allowlist-function "archive_entry_set_hardlink" \
--allowlist-function "archive_entry_hardlink" \
--blocklist-type "stat" \
--blacklist-type "timespec" \
--whitelist-function "archive_entry_stat" \
--whitelist-function "archive_set_error" \
--whitelist-function "archive_error_string" \
--whitelist-function "archive_errno" \
--blocklist-type "timespec" \
--allowlist-function "archive_entry_stat" \
--allowlist-function "archive_set_error" \
--allowlist-function "archive_error_string" \
--allowlist-function "archive_errno" \
\
--output $basedir/src/ffi/generated.rs \
\
Expand Down
7 changes: 4 additions & 3 deletions src/ffi/generated.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* automatically generated by rust-bindgen 0.59.1 */
/* automatically generated by rust-bindgen 0.71.1 */

#![allow(non_camel_case_types)]
#[cfg(target_os = "windows")]
use crate::stat;
#[cfg(not(target_os = "windows"))]
use libc::stat;
pub(crate) const ARCHIVE_EOF: i32 = 1;
pub(crate) const ARCHIVE_OK: i32 = 0;
Expand All @@ -12,7 +15,6 @@ pub(crate) const ARCHIVE_EXTRACT_TIME: u32 = 4;
pub(crate) const ARCHIVE_EXTRACT_ACL: u32 = 32;
pub(crate) const ARCHIVE_EXTRACT_FFLAGS: u32 = 64;
pub(crate) const ARCHIVE_EXTRACT_XATTR: u32 = 128;
pub(crate) type __int64_t = ::std::os::raw::c_long;
pub(crate) type __dev_t = ::std::os::raw::c_ulong;
pub(crate) type __uid_t = ::std::os::raw::c_uint;
pub(crate) type __gid_t = ::std::os::raw::c_uint;
Expand All @@ -23,7 +25,6 @@ pub(crate) type __off_t = ::std::os::raw::c_long;
pub(crate) type __time_t = ::std::os::raw::c_long;
pub(crate) type __blksize_t = ::std::os::raw::c_long;
pub(crate) type __blkcnt_t = ::std::os::raw::c_long;
pub(crate) type __ssize_t = ::std::os::raw::c_long;
pub(crate) type __syscall_slong_t = ::std::os::raw::c_long;
pub(crate) type la_int64_t = i64;
pub(crate) type la_ssize_t = isize;
Expand Down
11 changes: 8 additions & 3 deletions src/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use std::{

use libc::{c_int, c_void};

#[cfg(target_os = "windows")]
use crate::stat;
#[cfg(not(target_os = "windows"))]
use libc::stat;

use crate::{
error::archive_result, ffi, ffi::UTF8LocaleGuard, DecodeCallback, Error, Result,
READER_BUFFER_SIZE,
Expand All @@ -26,7 +31,7 @@ struct HeapReadSeekerPipe<R: Read + Seek> {
/// completion.
pub enum ArchiveContents {
/// Marks the start of an entry, either a file or a directory.
StartOfEntry(String, libc::stat),
StartOfEntry(String, stat),
/// A chunk of uncompressed data from the entry. Entries may have zero or
/// more chunks.
DataChunk(Vec<u8>),
Expand All @@ -42,7 +47,7 @@ pub enum ArchiveContents {
/// Gets called on an encounter of a new archive entry with the filename and
/// file status information of that entry.
/// The entry is processed on a return value of `true` and ignored on `false`.
pub type EntryFilterCallbackFn = dyn Fn(&str, &libc::stat) -> bool;
pub type EntryFilterCallbackFn = dyn Fn(&str, &stat) -> bool;

/// An iterator over the contents of an archive.
#[allow(clippy::module_name_repetitions)]
Expand Down Expand Up @@ -481,7 +486,7 @@ where
/// By default all entries are iterated.
pub fn filter<F>(mut self, filter: F) -> ArchiveIteratorBuilder<R>
where
F: Fn(&str, &libc::stat) -> bool + 'static,
F: Fn(&str, &stat) -> bool + 'static,
{
self.filter = Some(Box::new(filter));
self
Expand Down
19 changes: 19 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ use std::{

const READER_BUFFER_SIZE: usize = 16384;

/// A data type that represents the libc stat type on windows, not stat64
#[cfg(target_os = "windows")]
#[derive(Copy, Clone)]
#[repr(C)]
#[allow(non_camel_case_types)]
pub struct stat {
pub st_dev: libc::dev_t,
pub st_ino: libc::ino_t,
pub st_mode: u16,
pub st_nlink: libc::c_short,
pub st_uid: libc::c_short,
pub st_gid: libc::c_short,
pub st_rdev: libc::dev_t,
pub st_size: i32,
pub st_atime: libc::time_t,
pub st_mtime: libc::time_t,
pub st_ctime: libc::time_t,
}

/// Determine the ownership behavior when unpacking the archive.
#[derive(Clone, Copy, Debug)]
pub enum Ownership {
Expand Down
4 changes: 2 additions & 2 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,9 +541,9 @@ fn collect_iterate_results_with_encoding(

for content in &mut iter {
match content {
ArchiveContents::StartOfEntry(file_name, _) => {
ArchiveContents::StartOfEntry(file_name, stat) => {
assert!(name.is_empty());
assert_eq!(size, 0);
assert_eq!(stat.st_size == 0, file_name.ends_with('/'));
name = file_name;
}
ArchiveContents::DataChunk(data) => {
Expand Down