Fix windows compilation issues

This commit is contained in:
Jeremy Soller 2026-04-17 13:31:55 -06:00
parent 8c57060db2
commit 4afacccc8a
5 changed files with 59 additions and 22 deletions

View file

@ -189,6 +189,8 @@ fn zip_extract<R: io::Read + io::Seek, P: AsRef<Path>>(
if file.is_symlink() && (cfg!(unix) || cfg!(windows)) {
let mut target = Vec::with_capacity(file.size() as usize);
file.read_to_end(&mut target)?;
// File no longer needed, drop to allow reading target on windows
drop(file);
#[cfg(unix)]
{
@ -199,11 +201,15 @@ fn zip_extract<R: io::Read + io::Seek, P: AsRef<Path>>(
#[cfg(windows)]
{
let Ok(target) = String::from_utf8(target) else {
return Err(ZipError::InvalidArchive("Invalid UTF-8 as symlink target"));
return Err(ZipError::InvalidArchive(
"Invalid UTF-8 as symlink target".into(),
));
};
let target = target.into_boxed_str();
let target_is_dir_from_archive =
archive.shared.files.contains_key(&target) && is_dir(&target);
let target_is_dir_from_archive = match password {
None => archive.by_name(&target),
Some(pwd) => archive.by_name_decrypt(&target, pwd.as_bytes()),
}
.map_or(false, |x| x.is_dir());
let target_path = directory.as_ref().join(OsString::from(target.to_string()));
let target_is_dir = if target_is_dir_from_archive {
true

View file

@ -19,6 +19,7 @@ struct MimeIconKey {
struct MimeIconCache {
cache: FxHashMap<MimeIconKey, Option<icon::Handle>>,
#[cfg(unix)]
shared_mime_info: xdg_mime::SharedMimeInfo,
}
@ -26,10 +27,17 @@ impl MimeIconCache {
pub fn new() -> Self {
Self {
cache: FxHashMap::default(),
#[cfg(unix)]
shared_mime_info: xdg_mime::SharedMimeInfo::new(),
}
}
#[cfg(not(unix))]
pub fn get(&mut self, _key: MimeIconKey) -> Option<icon::Handle> {
None
}
#[cfg(unix)]
pub fn get(&mut self, key: MimeIconKey) -> Option<icon::Handle> {
self.cache
.entry(key)
@ -53,6 +61,16 @@ impl MimeIconCache {
static MIME_ICON_CACHE: LazyLock<Mutex<MimeIconCache>> =
LazyLock::new(|| Mutex::new(MimeIconCache::new()));
#[cfg(not(unix))]
pub fn mime_for_path(
path: impl AsRef<Path>,
metadata_opt: Option<&fs::Metadata>,
remote: bool,
) -> Mime {
mime_guess::from_path(path).first_or_octet_stream()
}
#[cfg(unix)]
pub fn mime_for_path(
path: impl AsRef<Path>,
metadata_opt: Option<&fs::Metadata>,
@ -100,8 +118,13 @@ pub fn mime_icon(mime: Mime, size: u16) -> icon::Handle {
}
}
#[cfg(not(unix))]
pub fn parent_mime_types(_mime: &Mime) -> Option<Vec<Mime>> {
None
}
#[cfg(unix)]
pub fn parent_mime_types(mime: &Mime) -> Option<Vec<Mime>> {
let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap();
mime_icon_cache.shared_mime_info.get_parents_aliased(mime)
}

View file

@ -41,6 +41,8 @@ use jiff_icu::ConvertFrom;
use mime_guess::{Mime, mime};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
use std::{
borrow::Cow,
cell::Cell,
@ -51,7 +53,6 @@ use std::{
fs::{self, File, Metadata},
hash::Hash,
io::{BufRead, BufReader},
os::unix::fs::MetadataExt,
path::{self, Path, PathBuf},
sync::{Arc, LazyLock, RwLock, atomic},
time::{Duration, Instant, SystemTime},
@ -4339,6 +4340,7 @@ impl Tab {
for item in self.items_opt().map_or(Vec::new(), |items| {
items.iter().filter(|item| item.selected).collect()
}) {
#[cfg(unix)]
if let (Some(path), Some(mode)) = (
item.path_opt(),
item.file_metadata()
@ -6356,22 +6358,23 @@ impl Tab {
} else {
total_size = total_size.saturating_add(metadata.len());
}
let mode = metadata.mode();
#[cfg(unix)]
user_name.insert(
uzers::get_user_by_uid(metadata.uid())
.and_then(|user| user.name().to_str().map(ToOwned::to_owned))
.unwrap_or_default(),
);
mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER));
#[cfg(unix)]
group_name.insert(
uzers::get_group_by_gid(metadata.gid())
.and_then(|group| group.name().to_str().map(ToOwned::to_owned))
.unwrap_or_default(),
);
mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP));
mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER));
{
let mode = metadata.mode();
user_name.insert(
uzers::get_user_by_uid(metadata.uid())
.and_then(|user| user.name().to_str().map(ToOwned::to_owned))
.unwrap_or_default(),
);
mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER));
group_name.insert(
uzers::get_group_by_gid(metadata.gid())
.and_then(|group| group.name().to_str().map(ToOwned::to_owned))
.unwrap_or_default(),
);
mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP));
mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER));
}
}
}
let mut mime_types: Vec<(String, u64)> = mime_type_counts.into_iter().collect();

View file

@ -1,11 +1,12 @@
use image::DynamicImage;
use md5::{Digest, Md5};
use rustc_hash::FxHashMap;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::{
error::Error,
fs::{self, File},
io::{self, BufReader, BufWriter},
os::unix::fs::PermissionsExt,
path::{Path, PathBuf},
sync::LazyLock,
time::UNIX_EPOCH,
@ -93,6 +94,7 @@ impl ThumbnailCacher {
}
pub fn update_with_temp_file(&self, temp_file: NamedTempFile) -> Result<&Path, Box<dyn Error>> {
#[cfg(unix)]
fs::set_permissions(temp_file.path(), fs::Permissions::from_mode(0o600))?;
self.update_thumbnail_text_metadata(temp_file.path())?;
fs::rename(temp_file.path(), &self.thumbnail_path)?;
@ -127,6 +129,7 @@ impl ThumbnailCacher {
pub fn create_fail_marker(&self) -> Result<(), Box<dyn Error>> {
if let Some(dir) = self.thumbnail_fail_marker_path.parent() {
fs::create_dir_all(dir)?;
#[cfg(unix)]
fs::set_permissions(dir, fs::Permissions::from_mode(0o700))?;
}

View file

@ -74,6 +74,8 @@ impl TrashExt for Trash {
}
}
// Not available on Windows only
#[cfg(not(target_os = "windows"))]
fn folders() -> Result<HashSet<PathBuf>, trash::Error> {
trash::os_limited::trash_folders()
}