Skip to content

Commit

Permalink
fix: implement the file copy process for Linux and Android separately (
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Oct 18, 2024
1 parent 5304331 commit cc9ca10
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 26 deletions.
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname"],"flagWords":[],"version":"0.2","language":"en"}
{"flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod"],"version":"0.2","language":"en"}
76 changes: 51 additions & 25 deletions yazi-shared/src/fs/fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async fn _paths_to_same_file(a: &Path, b: &Path) -> std::io::Result<bool> {
use windows_sys::Win32::{Foundation::{HANDLE, MAX_PATH}, Storage::FileSystem::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, GetFinalPathNameByHandleW, VOLUME_NAME_DOS}};

async fn final_name(p: &Path) -> std::io::Result<PathBuf> {
let file = tokio::fs::OpenOptions::new()
let file = fs::OpenOptions::new()
.access_mode(0)
.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)
.open(p)
Expand Down Expand Up @@ -190,31 +190,8 @@ pub fn copy_with_progress(
tokio::spawn({
let (from, to) = (from.to_owned(), to.to_owned());

let mut ft = std::fs::FileTimes::new();
cha.atime.map(|t| ft = ft.set_accessed(t));
cha.mtime.map(|t| ft = ft.set_modified(t));
#[cfg(target_os = "macos")]
{
use std::os::macos::fs::FileTimesExt;
cha.btime.map(|t| ft = ft.set_created(t));
}
#[cfg(windows)]
{
use std::os::windows::fs::FileTimesExt;
cha.btime.map(|t| ft = ft.set_created(t));
}

async move {
_ = match fs::copy(&from, &to).await {
Ok(len) => {
_ = tokio::task::spawn_blocking(move || {
std::fs::File::options().write(true).open(to).and_then(|f| f.set_times(ft)).ok();
})
.await;
tick_tx.send(Ok(len))
}
Err(e) => tick_tx.send(Err(e)),
};
tick_tx.send(_copy_with_progress(from, to, cha).await).ok();
}
});

Expand Down Expand Up @@ -259,6 +236,55 @@ pub fn copy_with_progress(
rx
}

async fn _copy_with_progress(from: PathBuf, to: PathBuf, cha: Cha) -> io::Result<u64> {
let mut ft = std::fs::FileTimes::new();
cha.atime.map(|t| ft = ft.set_accessed(t));
cha.mtime.map(|t| ft = ft.set_modified(t));
#[cfg(target_os = "macos")]
{
use std::os::macos::fs::FileTimesExt;
cha.btime.map(|t| ft = ft.set_created(t));
}
#[cfg(windows)]
{
use std::os::windows::fs::FileTimesExt;
cha.btime.map(|t| ft = ft.set_created(t));
}

let written;
#[cfg(any(target_os = "linux", target_os = "android"))]
{
use std::os::fd::AsRawFd;

let mut reader = fs::File::open(from).await?;
let mut writer = fs::OpenOptions::new()
.mode(cha.perm as u32)
.write(true)
.create(true)
.truncate(true)
.open(&to)
.await?;

written = io::copy(&mut reader, &mut writer).await?;
_ = tokio::task::spawn_blocking(move || {
unsafe { libc::fchmod(writer.as_raw_fd(), cha.perm) };
std::fs::File::options().write(true).open(to).and_then(|f| f.set_times(ft)).ok();
})
.await;
}

#[cfg(not(any(target_os = "linux", target_os = "android")))]
{
written = fs::copy(from, &to).await?;
_ = tokio::task::spawn_blocking(move || {
std::fs::File::options().write(true).open(to).and_then(|f| f.set_times(ft)).ok();
})
.await;
}

Ok(written)
}

pub async fn remove_dir_clean(dir: &Path) {
let Ok(mut it) = fs::read_dir(dir).await else { return };

Expand Down

0 comments on commit cc9ca10

Please sign in to comment.