diff --git a/Cargo.toml b/Cargo.toml index 3a39617..8b73f5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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] diff --git a/scripts/generate-ffi b/scripts/generate-ffi index 365dccd..c23cae3 100755 --- a/scripts/generate-ffi +++ b/scripts/generate-ffi @@ -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 \ \ diff --git a/src/ffi/generated.rs b/src/ffi/generated.rs index 50f04c4..12dceef 100644 --- a/src/ffi/generated.rs +++ b/src/ffi/generated.rs @@ -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; @@ -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; @@ -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; diff --git a/src/iterator.rs b/src/iterator.rs index 16e1d11..868e5dd 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -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, @@ -26,7 +31,7 @@ struct HeapReadSeekerPipe { /// 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), @@ -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)] @@ -481,7 +486,7 @@ where /// By default all entries are iterated. pub fn filter(mut self, filter: F) -> ArchiveIteratorBuilder where - F: Fn(&str, &libc::stat) -> bool + 'static, + F: Fn(&str, &stat) -> bool + 'static, { self.filter = Some(Box::new(filter)); self diff --git a/src/lib.rs b/src/lib.rs index 12a3fe9..8ba9c8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 { diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 6d18ad8..61478be 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -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) => {