X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-persister%2Fsrc%2Futil.rs;h=f26296794c6858a28fc4aa5bce46055a55657cb6;hb=3c6768706662f954b4d6140362743fdecc5bcd01;hp=daacb00f0cc3856449ead179c15554ae0c1a5a72;hpb=ee68ffa5fdfcfa8ee7fe70512d9e079d621083bc;p=rust-lightning diff --git a/lightning-persister/src/util.rs b/lightning-persister/src/util.rs index daacb00f..f2629679 100644 --- a/lightning-persister/src/util.rs +++ b/lightning-persister/src/util.rs @@ -3,6 +3,7 @@ extern crate winapi; use std::fs; use std::path::{Path, PathBuf}; +use std::io::{BufWriter, Write}; #[cfg(not(target_os = "windows"))] use std::os::unix::io::AsRawFd; @@ -14,13 +15,12 @@ use { }; pub(crate) trait DiskWriteable { - fn write_to_file(&self, writer: &mut fs::File) -> Result<(), std::io::Error>; + fn write_to_file(&self, writer: &mut W) -> Result<(), std::io::Error>; } -pub(crate) fn get_full_filepath(filepath: String, filename: String) -> String { - let mut path = PathBuf::from(filepath); - path.push(filename); - path.to_str().unwrap().to_string() +pub(crate) fn get_full_filepath(mut filepath: PathBuf, filename: String) -> String { + filepath.push(filename); + filepath.to_str().unwrap().to_string() } #[cfg(target_os = "windows")] @@ -40,7 +40,7 @@ fn path_to_windows_str>(path: T) -> Vec(path: String, filename: String, data: &D) -> std::io::Result<()> { +pub(crate) fn write_to_file(path: PathBuf, filename: String, data: &D) -> std::io::Result<()> { fs::create_dir_all(path.clone())?; // Do a crazy dance with lots of fsync()s to be overly cautious here... // We never want to end up in a state where we've lost the old data, or end up using the @@ -53,9 +53,9 @@ pub(crate) fn write_to_file(path: String, filename: String, da { // Note that going by rust-lang/rust@d602a6b, on MacOS it is only safe to use // rust stdlib 1.36 or higher. - let mut f = fs::File::create(&tmp_filename)?; - data.write_to_file(&mut f)?; - f.sync_all()?; + let mut buf = BufWriter::new(fs::File::create(&tmp_filename)?); + data.write_to_file(&mut buf)?; + buf.into_inner()?.sync_all()?; } // Fsync the parent directory on Unix. #[cfg(not(target_os = "windows"))] @@ -92,10 +92,11 @@ mod tests { use std::fs; use std::io; use std::io::Write; + use std::path::PathBuf; struct TestWriteable{} impl DiskWriteable for TestWriteable { - fn write_to_file(&self, writer: &mut fs::File) -> Result<(), io::Error> { + fn write_to_file(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&[42; 1]) } } @@ -113,7 +114,7 @@ mod tests { let mut perms = fs::metadata(path.to_string()).unwrap().permissions(); perms.set_readonly(true); fs::set_permissions(path.to_string(), perms).unwrap(); - match write_to_file(path.to_string(), filename, &test_writeable) { + match write_to_file(PathBuf::from(path.to_string()), filename, &test_writeable) { Err(e) => assert_eq!(e.kind(), io::ErrorKind::PermissionDenied), _ => panic!("Unexpected error message") } @@ -131,11 +132,11 @@ mod tests { fn test_rename_failure() { let test_writeable = TestWriteable{}; let filename = "test_rename_failure_filename"; - let path = "test_rename_failure_dir"; + let path = PathBuf::from("test_rename_failure_dir"); // Create the channel data file and make it a directory. - fs::create_dir_all(get_full_filepath(path.to_string(), filename.to_string())).unwrap(); - match write_to_file(path.to_string(), filename.to_string(), &test_writeable) { - Err(e) => assert_eq!(e.kind(), io::ErrorKind::Other), + fs::create_dir_all(get_full_filepath(path.clone(), filename.to_string())).unwrap(); + match write_to_file(path.clone(), filename.to_string(), &test_writeable) { + Err(e) => assert_eq!(e.raw_os_error(), Some(libc::EISDIR)), _ => panic!("Unexpected Ok(())") } fs::remove_dir_all(path).unwrap(); @@ -145,15 +146,15 @@ mod tests { fn test_diskwriteable_failure() { struct FailingWriteable {} impl DiskWriteable for FailingWriteable { - fn write_to_file(&self, _writer: &mut fs::File) -> Result<(), std::io::Error> { + fn write_to_file(&self, _writer: &mut W) -> Result<(), std::io::Error> { Err(std::io::Error::new(std::io::ErrorKind::Other, "expected failure")) } } let filename = "test_diskwriteable_failure"; - let path = "test_diskwriteable_failure_dir"; + let path = PathBuf::from("test_diskwriteable_failure_dir"); let test_writeable = FailingWriteable{}; - match write_to_file(path.to_string(), filename.to_string(), &test_writeable) { + match write_to_file(path.clone(), filename.to_string(), &test_writeable) { Err(e) => { assert_eq!(e.kind(), std::io::ErrorKind::Other); assert_eq!(e.get_ref().unwrap().to_string(), "expected failure"); @@ -170,7 +171,7 @@ mod tests { fn test_tmp_file_creation_failure() { let test_writeable = TestWriteable{}; let filename = "test_tmp_file_creation_failure_filename".to_string(); - let path = "test_tmp_file_creation_failure_dir".to_string(); + let path = PathBuf::from("test_tmp_file_creation_failure_dir"); // Create the tmp file and make it a directory. let tmp_path = get_full_filepath(path.clone(), format!("{}.tmp", filename.clone())); @@ -178,7 +179,7 @@ mod tests { match write_to_file(path, filename, &test_writeable) { Err(e) => { #[cfg(not(target_os = "windows"))] - assert_eq!(e.kind(), io::ErrorKind::Other); + assert_eq!(e.raw_os_error(), Some(libc::EISDIR)); #[cfg(target_os = "windows")] assert_eq!(e.kind(), io::ErrorKind::PermissionDenied); }