@@ -13,7 +13,7 @@ use object::read::macho::FatArch;
1313use tempfile:: Builder as TempFileBuilder ;
1414
1515use std:: error:: Error ;
16- use std:: fs:: File ;
16+ use std:: fs:: { self , File } ;
1717use std:: io:: { self , Write } ;
1818use std:: path:: { Path , PathBuf } ;
1919
@@ -276,29 +276,34 @@ impl<'a> ArArchiveBuilder<'a> {
276276 // This prevents programs (including rustc) from attempting to read a partial archive.
277277 // It also enables writing an archive with the same filename as a dependency on Windows as
278278 // required by a test.
279- let mut archive_tmpfile = TempFileBuilder :: new ( )
279+ // The tempfile crate currently uses 0o600 as mode for the temporary files and directories
280+ // it creates. We need it to be the default mode for back compat reasons however. (See
281+ // #107495) To handle this we are telling tempfile to create a temporary directory instead
282+ // and then inside this directory create a file using File::create.
283+ let archive_tmpdir = TempFileBuilder :: new ( )
280284 . suffix ( ".temp-archive" )
281- . tempfile_in ( output. parent ( ) . unwrap_or_else ( || Path :: new ( "" ) ) )
282- . map_err ( |err| io_error_context ( "couldn't create a temp file" , err) ) ?;
283-
284- write_archive_to_stream (
285- archive_tmpfile. as_file_mut ( ) ,
286- & entries,
287- true ,
288- archive_kind,
289- true ,
290- false ,
291- ) ?;
285+ . tempdir_in ( output. parent ( ) . unwrap_or_else ( || Path :: new ( "" ) ) )
286+ . map_err ( |err| {
287+ io_error_context ( "couldn't create a directory for the temp file" , err)
288+ } ) ?;
289+ let archive_tmpfile_path = archive_tmpdir. path ( ) . join ( "tmp.a" ) ;
290+ let mut archive_tmpfile = File :: create_new ( & archive_tmpfile_path)
291+ . map_err ( |err| io_error_context ( "couldn't create the temp file" , err) ) ?;
292+
293+ write_archive_to_stream ( & mut archive_tmpfile, & entries, true , archive_kind, true , false ) ?;
294+ drop ( archive_tmpfile) ;
292295
293296 let any_entries = !entries. is_empty ( ) ;
294297 drop ( entries) ;
295298 // Drop src_archives to unmap all input archives, which is necessary if we want to write the
296299 // output archive to the same location as an input archive on Windows.
297300 drop ( self . src_archives ) ;
298301
299- archive_tmpfile
300- . persist ( output)
301- . map_err ( |err| io_error_context ( "failed to rename archive file" , err. error ) ) ?;
302+ fs:: rename ( archive_tmpfile_path, output)
303+ . map_err ( |err| io_error_context ( "failed to rename archive file" , err) ) ?;
304+ archive_tmpdir
305+ . close ( )
306+ . map_err ( |err| io_error_context ( "failed to remove temporary directory" , err) ) ?;
302307
303308 Ok ( any_entries)
304309 }
0 commit comments