@@ -13,7 +13,7 @@ use object::read::macho::FatArch;
13
13
use tempfile:: Builder as TempFileBuilder ;
14
14
15
15
use std:: error:: Error ;
16
- use std:: fs:: File ;
16
+ use std:: fs:: { self , File } ;
17
17
use std:: io:: { self , Write } ;
18
18
use std:: path:: { Path , PathBuf } ;
19
19
@@ -276,29 +276,34 @@ impl<'a> ArArchiveBuilder<'a> {
276
276
// This prevents programs (including rustc) from attempting to read a partial archive.
277
277
// It also enables writing an archive with the same filename as a dependency on Windows as
278
278
// 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 ( )
280
284
. 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) ;
292
295
293
296
let any_entries = !entries. is_empty ( ) ;
294
297
drop ( entries) ;
295
298
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
296
299
// output archive to the same location as an input archive on Windows.
297
300
drop ( self . src_archives ) ;
298
301
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) ) ?;
302
307
303
308
Ok ( any_entries)
304
309
}
0 commit comments