1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 12:37:49 +00:00

Merge pull request #6547 from Kev1n8/remove-crash-sync

sync: replace crash! with USimpleError
This commit is contained in:
Sylvestre Ledru 2024-07-07 12:19:13 +02:00 committed by GitHub
commit 33a04bed2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -35,40 +35,41 @@ mod platform {
use std::fs::File; use std::fs::File;
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use uucore::error::UResult;
/// # Safety /// # Safety
/// This function is unsafe because it calls `libc::sync` or `libc::syscall` which are unsafe. /// This function is unsafe because it calls `libc::sync` or `libc::syscall` which are unsafe.
pub unsafe fn do_sync() -> isize { pub unsafe fn do_sync() -> UResult<()> {
// see https://github.com/rust-lang/libc/pull/2161 // see https://github.com/rust-lang/libc/pull/2161
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
libc::syscall(libc::SYS_sync); libc::syscall(libc::SYS_sync);
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
libc::sync(); libc::sync();
0 Ok(())
} }
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
/// # Safety /// # Safety
/// This function is unsafe because it calls `libc::syscall` which is unsafe. /// This function is unsafe because it calls `libc::syscall` which is unsafe.
pub unsafe fn do_syncfs(files: Vec<String>) -> isize { pub unsafe fn do_syncfs(files: Vec<String>) -> UResult<()> {
for path in files { for path in files {
let f = File::open(path).unwrap(); let f = File::open(path).unwrap();
let fd = f.as_raw_fd(); let fd = f.as_raw_fd();
libc::syscall(libc::SYS_syncfs, fd); libc::syscall(libc::SYS_syncfs, fd);
} }
0 Ok(())
} }
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
/// # Safety /// # Safety
/// This function is unsafe because it calls `libc::syscall` which is unsafe. /// This function is unsafe because it calls `libc::syscall` which is unsafe.
pub unsafe fn do_fdatasync(files: Vec<String>) -> isize { pub unsafe fn do_fdatasync(files: Vec<String>) -> UResult<()> {
for path in files { for path in files {
let f = File::open(path).unwrap(); let f = File::open(path).unwrap();
let fd = f.as_raw_fd(); let fd = f.as_raw_fd();
libc::syscall(libc::SYS_fdatasync, fd); libc::syscall(libc::SYS_fdatasync, fd);
} }
0 Ok(())
} }
} }
@ -77,7 +78,7 @@ mod platform {
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::os::windows::prelude::*; use std::os::windows::prelude::*;
use std::path::Path; use std::path::Path;
use uucore::crash; use uucore::error::{UResult, USimpleError};
use uucore::wide::{FromWide, ToWide}; use uucore::wide::{FromWide, ToWide};
use windows_sys::Win32::Foundation::{ use windows_sys::Win32::Foundation::{
GetLastError, ERROR_NO_MORE_FILES, HANDLE, INVALID_HANDLE_VALUE, MAX_PATH, GetLastError, ERROR_NO_MORE_FILES, HANDLE, INVALID_HANDLE_VALUE, MAX_PATH,
@ -89,50 +90,60 @@ mod platform {
/// # Safety /// # Safety
/// This function is unsafe because it calls an unsafe function. /// This function is unsafe because it calls an unsafe function.
unsafe fn flush_volume(name: &str) { unsafe fn flush_volume(name: &str) -> UResult<()> {
let name_wide = name.to_wide_null(); let name_wide = name.to_wide_null();
if GetDriveTypeW(name_wide.as_ptr()) == DRIVE_FIXED { if GetDriveTypeW(name_wide.as_ptr()) == DRIVE_FIXED {
let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash
match OpenOptions::new().write(true).open(sliced_name) { match OpenOptions::new().write(true).open(sliced_name) {
Ok(file) => { Ok(file) => {
if FlushFileBuffers(file.as_raw_handle() as HANDLE) == 0 { if FlushFileBuffers(file.as_raw_handle() as HANDLE) == 0 {
crash!(GetLastError() as i32, "failed to flush file buffer"); Err(USimpleError::new(
GetLastError() as i32,
"failed to flush file buffer",
))
} else {
Ok(())
} }
} }
Err(e) => crash!( Err(e) => Err(USimpleError::new(
e.raw_os_error().unwrap_or(1), e.raw_os_error().unwrap_or(1),
"failed to create volume handle" "failed to create volume handle",
), )),
} }
} else {
Ok(())
} }
} }
/// # Safety /// # Safety
/// This function is unsafe because it calls an unsafe function. /// This function is unsafe because it calls an unsafe function.
unsafe fn find_first_volume() -> (String, HANDLE) { unsafe fn find_first_volume() -> UResult<(String, HANDLE)> {
let mut name: [u16; MAX_PATH as usize] = [0; MAX_PATH as usize]; let mut name: [u16; MAX_PATH as usize] = [0; MAX_PATH as usize];
let handle = FindFirstVolumeW(name.as_mut_ptr(), name.len() as u32); let handle = FindFirstVolumeW(name.as_mut_ptr(), name.len() as u32);
if handle == INVALID_HANDLE_VALUE { if handle == INVALID_HANDLE_VALUE {
crash!(GetLastError() as i32, "failed to find first volume"); return Err(USimpleError::new(
GetLastError() as i32,
"failed to find first volume",
));
} }
(String::from_wide_null(&name), handle) Ok((String::from_wide_null(&name), handle))
} }
/// # Safety /// # Safety
/// This function is unsafe because it calls an unsafe function. /// This function is unsafe because it calls an unsafe function.
unsafe fn find_all_volumes() -> Vec<String> { unsafe fn find_all_volumes() -> UResult<Vec<String>> {
let (first_volume, next_volume_handle) = find_first_volume(); let (first_volume, next_volume_handle) = find_first_volume()?;
let mut volumes = vec![first_volume]; let mut volumes = vec![first_volume];
loop { loop {
let mut name: [u16; MAX_PATH as usize] = [0; MAX_PATH as usize]; let mut name: [u16; MAX_PATH as usize] = [0; MAX_PATH as usize];
if FindNextVolumeW(next_volume_handle, name.as_mut_ptr(), name.len() as u32) == 0 { if FindNextVolumeW(next_volume_handle, name.as_mut_ptr(), name.len() as u32) == 0 {
match GetLastError() { return match GetLastError() {
ERROR_NO_MORE_FILES => { ERROR_NO_MORE_FILES => {
FindVolumeClose(next_volume_handle); FindVolumeClose(next_volume_handle);
return volumes; Ok(volumes)
}
err => crash!(err as i32, "failed to find next volume"),
} }
err => Err(USimpleError::new(err as i32, "failed to find next volume")),
};
} else { } else {
volumes.push(String::from_wide_null(&name)); volumes.push(String::from_wide_null(&name));
} }
@ -141,17 +152,17 @@ mod platform {
/// # Safety /// # Safety
/// This function is unsafe because it calls `find_all_volumes` which is unsafe. /// This function is unsafe because it calls `find_all_volumes` which is unsafe.
pub unsafe fn do_sync() -> isize { pub unsafe fn do_sync() -> UResult<()> {
let volumes = find_all_volumes(); let volumes = find_all_volumes()?;
for vol in &volumes { for vol in &volumes {
flush_volume(vol); flush_volume(vol)?;
} }
0 Ok(())
} }
/// # Safety /// # Safety
/// This function is unsafe because it calls `find_all_volumes` which is unsafe. /// This function is unsafe because it calls `find_all_volumes` which is unsafe.
pub unsafe fn do_syncfs(files: Vec<String>) -> isize { pub unsafe fn do_syncfs(files: Vec<String>) -> UResult<()> {
for path in files { for path in files {
flush_volume( flush_volume(
Path::new(&path) Path::new(&path)
@ -161,9 +172,9 @@ mod platform {
.as_os_str() .as_os_str()
.to_str() .to_str()
.unwrap(), .unwrap(),
); )?;
} }
0 Ok(())
} }
} }
@ -206,12 +217,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[allow(clippy::if_same_then_else)] #[allow(clippy::if_same_then_else)]
if matches.get_flag(options::FILE_SYSTEM) { if matches.get_flag(options::FILE_SYSTEM) {
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))] #[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
syncfs(files); syncfs(files)?;
} else if matches.get_flag(options::DATA) { } else if matches.get_flag(options::DATA) {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
fdatasync(files); fdatasync(files)?;
} else { } else {
sync(); sync()?;
} }
Ok(()) Ok(())
} }
@ -245,16 +256,16 @@ pub fn uu_app() -> Command {
) )
} }
fn sync() -> isize { fn sync() -> UResult<()> {
unsafe { platform::do_sync() } unsafe { platform::do_sync() }
} }
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))] #[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
fn syncfs(files: Vec<String>) -> isize { fn syncfs(files: Vec<String>) -> UResult<()> {
unsafe { platform::do_syncfs(files) } unsafe { platform::do_syncfs(files) }
} }
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
fn fdatasync(files: Vec<String>) -> isize { fn fdatasync(files: Vec<String>) -> UResult<()> {
unsafe { platform::do_fdatasync(files) } unsafe { platform::do_fdatasync(files) }
} }