@@ -7,21 +7,14 @@ use std::path::{Path, PathBuf};
77#[ cfg( not( target_os = "windows" ) ) ]
88use std:: os:: unix:: io:: AsRawFd ;
99
10+ use lightning:: util:: ser:: Writeable ;
11+
1012#[ cfg( target_os = "windows" ) ]
1113use {
1214 std:: ffi:: OsStr ,
1315 std:: os:: windows:: ffi:: OsStrExt
1416} ;
1517
16- pub ( crate ) trait DiskWriteable {
17- fn write_to_file ( & self , writer : & mut fs:: File ) -> Result < ( ) , std:: io:: Error > ;
18- }
19-
20- pub ( crate ) fn get_full_filepath ( mut filepath : PathBuf , filename : String ) -> String {
21- filepath. push ( filename) ;
22- filepath. to_str ( ) . unwrap ( ) . to_string ( )
23- }
24-
2518#[ cfg( target_os = "windows" ) ]
2619macro_rules! call {
2720 ( $e: expr) => (
@@ -39,21 +32,25 @@ fn path_to_windows_str<T: AsRef<OsStr>>(path: T) -> Vec<winapi::shared::ntdef::W
3932}
4033
4134#[ allow( bare_trait_objects) ]
42- pub ( crate ) fn write_to_file < D : DiskWriteable > ( path : PathBuf , filename : String , data : & D ) -> std:: io:: Result < ( ) > {
43- fs:: create_dir_all ( path. clone ( ) ) ?;
35+ pub ( crate ) fn write_to_file < W : Writeable > ( filename_with_path : String , data : & W ) -> std:: io:: Result < ( ) > {
36+ let mut tmp_filename = filename_with_path. clone ( ) ;
37+ tmp_filename. push_str ( ".tmp" ) ;
38+
39+ let full_path = PathBuf :: from ( & filename_with_path) ;
40+ let path = full_path. parent ( ) . unwrap ( ) ;
41+ fs:: create_dir_all ( path) ?;
4442 // Do a crazy dance with lots of fsync()s to be overly cautious here...
4543 // We never want to end up in a state where we've lost the old data, or end up using the
4644 // old data on power loss after we've returned.
4745 // The way to atomically write a file on Unix platforms is:
4846 // open(tmpname), write(tmpfile), fsync(tmpfile), close(tmpfile), rename(), fsync(dir)
49- let filename_with_path = get_full_filepath ( path, filename) ;
50- let tmp_filename = format ! ( "{}.tmp" , filename_with_path. clone( ) ) ;
47+
5148
5249 {
5350 // Note that going by rust-lang/rust@d602a6b, on MacOS it is only safe to use
5451 // rust stdlib 1.36 or higher.
5552 let mut f = fs:: File :: create ( & tmp_filename) ?;
56- data. write_to_file ( & mut f) ?;
53+ data. write ( & mut f) ?;
5754 f. sync_all ( ) ?;
5855 }
5956 // Fsync the parent directory on Unix.
@@ -87,15 +84,17 @@ pub(crate) fn write_to_file<D: DiskWriteable>(path: PathBuf, filename: String, d
8784
8885#[ cfg( test) ]
8986mod tests {
90- use super :: { DiskWriteable , get_full_filepath, write_to_file} ;
87+ use lightning:: util:: ser:: { Writer , Writeable } ;
88+
89+ use super :: { write_to_file} ;
9190 use std:: fs;
9291 use std:: io;
9392 use std:: io:: Write ;
94- use std:: path:: PathBuf ;
93+ use std:: path:: { PathBuf , MAIN_SEPARATOR } ;
9594
9695 struct TestWriteable { }
97- impl DiskWriteable for TestWriteable {
98- fn write_to_file ( & self , writer : & mut fs :: File ) -> Result < ( ) , io:: Error > {
96+ impl Writeable for TestWriteable {
97+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , std :: io:: Error > {
9998 writer. write_all ( & [ 42 ; 1 ] )
10099 }
101100 }
@@ -113,7 +112,8 @@ mod tests {
113112 let mut perms = fs:: metadata ( path. to_string ( ) ) . unwrap ( ) . permissions ( ) ;
114113 perms. set_readonly ( true ) ;
115114 fs:: set_permissions ( path. to_string ( ) , perms) . unwrap ( ) ;
116- match write_to_file ( PathBuf :: from ( path. to_string ( ) ) , filename, & test_writeable) {
115+
116+ match write_to_file ( format ! ( "{}{}{}" , path, MAIN_SEPARATOR , filename) , & test_writeable) {
117117 Err ( e) => assert_eq ! ( e. kind( ) , io:: ErrorKind :: PermissionDenied ) ,
118118 _ => panic ! ( "Unexpected error message" )
119119 }
@@ -131,10 +131,11 @@ mod tests {
131131 fn test_rename_failure ( ) {
132132 let test_writeable = TestWriteable { } ;
133133 let filename = "test_rename_failure_filename" ;
134- let path = PathBuf :: from ( "test_rename_failure_dir" ) ;
134+ let path = "test_rename_failure_dir" ;
135+ let full_file_path = format ! ( "{}{}{}" , path, MAIN_SEPARATOR , filename) ;
135136 // Create the channel data file and make it a directory.
136- fs:: create_dir_all ( get_full_filepath ( path . clone ( ) , filename . to_string ( ) ) ) . unwrap ( ) ;
137- match write_to_file ( path . clone ( ) , filename . to_string ( ) , & test_writeable) {
137+ fs:: create_dir_all ( full_file_path . clone ( ) ) . unwrap ( ) ;
138+ match write_to_file ( full_file_path , & test_writeable) {
138139 Err ( e) => assert_eq ! ( e. raw_os_error( ) , Some ( libc:: EISDIR ) ) ,
139140 _ => panic ! ( "Unexpected Ok(())" )
140141 }
@@ -144,16 +145,17 @@ mod tests {
144145 #[ test]
145146 fn test_diskwriteable_failure ( ) {
146147 struct FailingWriteable { }
147- impl DiskWriteable for FailingWriteable {
148- fn write_to_file ( & self , _writer : & mut fs :: File ) -> Result < ( ) , std:: io:: Error > {
148+ impl Writeable for FailingWriteable {
149+ fn write < W : Writer > ( & self , _writer : & mut W ) -> Result < ( ) , std:: io:: Error > {
149150 Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "expected failure" ) )
150151 }
151152 }
152153
153154 let filename = "test_diskwriteable_failure" ;
154- let path = PathBuf :: from ( "test_diskwriteable_failure_dir" ) ;
155+ let path = "test_diskwriteable_failure_dir" ;
155156 let test_writeable = FailingWriteable { } ;
156- match write_to_file ( path. clone ( ) , filename. to_string ( ) , & test_writeable) {
157+ let full_path = format ! ( "{}{}{}" , path, MAIN_SEPARATOR , filename) ;
158+ match write_to_file ( full_path. clone ( ) , & test_writeable) {
157159 Err ( e) => {
158160 assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: Other ) ;
159161 assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "expected failure" ) ;
@@ -170,12 +172,11 @@ mod tests {
170172 fn test_tmp_file_creation_failure ( ) {
171173 let test_writeable = TestWriteable { } ;
172174 let filename = "test_tmp_file_creation_failure_filename" . to_string ( ) ;
173- let path = PathBuf :: from ( "test_tmp_file_creation_failure_dir" ) ;
174-
175- // Create the tmp file and make it a directory.
176- let tmp_path = get_full_filepath ( path. clone ( ) , format ! ( "{}.tmp" , filename. clone( ) ) ) ;
175+ let path = "test_tmp_file_creation_failure_dir" ;
176+ let tmp_path = format ! ( "{}{}{}.tmp" , path, MAIN_SEPARATOR , filename. clone( ) ) ;
177+ let full_filepath = format ! ( "{}{}{}" , path, MAIN_SEPARATOR , filename) ;
177178 fs:: create_dir_all ( tmp_path) . unwrap ( ) ;
178- match write_to_file ( path , filename , & test_writeable) {
179+ match write_to_file ( full_filepath , & test_writeable) {
179180 Err ( e) => {
180181 #[ cfg( not( target_os = "windows" ) ) ]
181182 assert_eq ! ( e. raw_os_error( ) , Some ( libc:: EISDIR ) ) ;
0 commit comments