From 54590c050718f6b0fedbb0fa5d0997ca5997d2c5 Mon Sep 17 00:00:00 2001 From: anastygnome Date: Sat, 4 Jun 2022 11:41:44 +0200 Subject: [PATCH 1/2] Implement the --sync flag for df. (fixes #3564) This PR reuses the defined --sync flag for df, which was previously a no-op, assigns its default value and uses the fact that get_all_filesystems takes CLI options as a parameter to perform a sync operation before any fs call. Fixes #3564 Signed-off-by: anastygnome --- src/uu/df/src/df.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 5bd478fd9..ca42b56ed 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -87,6 +87,9 @@ struct Options { /// types will *not* be listed. exclude: Option>, + /// Whether to sync before operating. + sync: bool, + /// Whether to show a final row comprising the totals for each column. show_total: bool, @@ -104,6 +107,7 @@ impl Default for Options { header_mode: Default::default(), include: Default::default(), exclude: Default::default(), + sync: Default::default(), show_total: Default::default(), columns: vec![ Column::Source, @@ -178,6 +182,7 @@ impl Options { Ok(Self { show_local_fs: matches.is_present(OPT_LOCAL), show_all_fs: matches.is_present(OPT_ALL), + sync: matches.is_present(OPT_SYNC), block_size: read_block_size(matches).map_err(|e| match e { ParseSizeError::InvalidSuffix(s) => OptionsError::InvalidSuffix(s), ParseSizeError::SizeTooBig(_) => OptionsError::BlockSizeTooLarge( @@ -325,9 +330,21 @@ fn filter_mount_list(vmi: Vec, opt: &Options) -> Vec { /// Get all currently mounted filesystems. /// -/// `opt` excludes certain filesystems from consideration; see +/// `opt` excludes certain filesystems from consideration and allows for the synchronization of filesystems before running; see /// [`Options`] for more information. + fn get_all_filesystems(opt: &Options) -> Vec { + // Run a sync call before any operation if so instructed. + if opt.sync { + #[cfg(not(windows))] + unsafe { + #[cfg(not(target_os = "android"))] + uucore::libc::sync(); + #[cfg(target_os = "android")] + uucore::libc::syscall(uucore::libc::SYS_sync); + } + } + // The list of all mounted filesystems. // // Filesystems excluded by the command-line options are @@ -559,7 +576,7 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(OPT_SYNC) .long("sync") .overrides_with_all(&[OPT_NO_SYNC, OPT_SYNC]) - .help("invoke sync before getting usage info"), + .help("invoke sync before getting usage info (non-windows only)"), ) .arg( Arg::new(OPT_TYPE) From f5ae859c388b3412de804c1022f6cfcc3e640b07 Mon Sep 17 00:00:00 2001 From: anastygnome Date: Sat, 4 Jun 2022 12:08:36 +0200 Subject: [PATCH 2/2] Adds a test for sync. It is probably too hard to verify that the sync is actually performed, so we just check that we have a test using the code path, pro forma. Signed-off-by: anastygnome --- tests/by-util/test_df.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/by-util/test_df.rs b/tests/by-util/test_df.rs index 4206c4c82..13cfdcef4 100644 --- a/tests/by-util/test_df.rs +++ b/tests/by-util/test_df.rs @@ -28,6 +28,11 @@ fn test_df_compatible_si() { new_ucmd!().arg("-aH").succeeds(); } +#[test] +fn test_df_compatible_sync() { + new_ucmd!().arg("--sync").succeeds(); +} + #[test] fn test_df_arguments_override_themselves() { new_ucmd!().args(&["--help", "--help"]).succeeds();