Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ feat_Tier1 = [
## (primary platforms) feature sets
# "feat_wasm" == set of utilities which can be built for wasm target
# We don't need to support all of wasm targets. So the ambiguous name is used at here
feat_wasm = ["feat_common_core", "nproc"]
feat_wasm = ["feat_common_core", "nproc", "sync"]
# "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms.
feat_os_unix = [
"feat_Tier1",
Expand Down
2 changes: 1 addition & 1 deletion src/uu/sync/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sync-usage = sync [OPTION]... FILE...

# Help messages
sync-help-file-system = sync the file systems that contain the files (Linux and Windows only)
sync-help-data = sync only file data, no unneeded metadata (Linux only)
sync-help-data = sync only file data, no unneeded metadata

# Error messages
sync-error-data-needs-argument = --data needs at least one argument
Expand Down
2 changes: 1 addition & 1 deletion src/uu/sync/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sync-usage = sync [OPTION]... FICHIER...

# Messages d'aide
sync-help-file-system = synchroniser les systèmes de fichiers qui contiennent les fichiers (Linux et Windows uniquement)
sync-help-data = synchroniser seulement les données des fichiers, pas les métadonnées inutiles (Linux uniquement)
sync-help-data = synchroniser seulement les données des fichiers, pas les métadonnées inutiles

# Messages d'erreur
sync-error-data-needs-argument = --data nécessite au moins un argument
Expand Down
45 changes: 38 additions & 7 deletions src/uu/sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ pub mod options {

static ARG_FILES: &str = "files";

#[cfg(unix)]
#[cfg(not(windows))]
mod platform {
#[cfg(unix)]
use std::fs::{File, OpenOptions};
#[cfg(unix)]
use std::os::unix::fs::OpenOptionsExt;
#[cfg(unix)]
use uucore::display::Quotable;
#[cfg(unix)]
use uucore::error::FromIo;
#[cfg(unix)]
use uucore::translate;

use uucore::error::UResult;
Expand All @@ -33,13 +38,16 @@ mod platform {
reason = "fn sig must match on all platforms"
)]
pub fn do_sync() -> UResult<()> {
// maximize compatibility of scripts by noop on targets global sync is impossible
#[cfg(unix)]
rustix::fs::sync();
Ok(())
}

/// Opens a file and resets its `O_NONBLOCK` flag to match GNU behavior.
/// Returns the opened file or an error if opening fails.
/// Logs a warning if fcntl fails but doesn't abort the operation.
#[cfg(unix)]
fn open_and_reset_nonblock(path: &str) -> UResult<File> {
let f = OpenOptions::new()
.read(true)
Expand All @@ -57,6 +65,7 @@ mod platform {
Ok(f)
}

#[cfg(unix)]
pub fn do_sync_with<F>(files: &[String], op: F) -> UResult<()>
where
F: Fn(File) -> std::io::Result<()>,
Expand All @@ -76,10 +85,6 @@ mod platform {
rustix::fs::syncfs(f).map_err(std::io::Error::from)
})
}

pub fn do_fdatasync(files: &[String]) -> UResult<()> {
do_sync_with(files, |f| f.sync_data())
}
}

#[cfg(windows)]
Expand Down Expand Up @@ -248,7 +253,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
syncfs(&files)?;
}
} else if matches.get_flag(options::DATA) {
#[cfg(unix)]
fdatasync(&files)?;
} else {
sync()?;
Expand Down Expand Up @@ -297,5 +301,32 @@ fn syncfs(files: &[String]) -> UResult<()> {

#[cfg(unix)]
fn fdatasync(files: &[String]) -> UResult<()> {
platform::do_fdatasync(files)
platform::do_sync_with(files, |f| f.sync_data())
}

#[cfg(not(unix))]
fn fdatasync(files: &[String]) -> UResult<()> {
do_sync_with_regular_file(files, |f| f.sync_data())
}

#[cfg(not(unix))]
fn do_sync_with_regular_file<F>(files: &[String], op: F) -> UResult<()>
where
F: Fn(std::fs::File) -> std::io::Result<()>,
{
#[cfg(windows)]
use std::os::windows::fs::OpenOptionsExt as _;
use uucore::error::FromIo;
for path in files {
let mut f = std::fs::OpenOptions::new();
f.read(true);
#[cfg(windows)]
f.write(true);
// allow opening directory
#[cfg(windows)]
f.custom_flags(windows_sys::Win32::Storage::FileSystem::FILE_FLAG_BACKUP_SEMANTICS);
op(f.open(path)?)
.map_err_context(|| translate!("sync-error-syncing-file", "file" => path.quote()))?;
}
Ok(())
}
Loading