diff options
author | Alan Modra <amodra@gmail.com> | 2021-02-23 12:10:58 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-02-24 09:34:42 +1030 |
commit | c42c71a1527dd70417d3966dce7ba9edbcf4bdb4 (patch) | |
tree | c84495ca493b5b03e8e144701fcc276a01d736d5 /binutils/objcopy.c | |
parent | cca8873dd5a6015d5557ea44bc1ea9c252435a29 (diff) | |
download | gdb-c42c71a1527dd70417d3966dce7ba9edbcf4bdb4.zip gdb-c42c71a1527dd70417d3966dce7ba9edbcf4bdb4.tar.gz gdb-c42c71a1527dd70417d3966dce7ba9edbcf4bdb4.tar.bz2 |
Use make_tempname file descriptor in smart_rename
This patch makes use of the temp file descriptor in smart_rename
rather than reopening the file. I don't believe there is a security
issue in reopening the file, but this way is one less directory
operation. The patch also attempts to preserve S_ISUID and S_ISGID.
PR 27456
* bucomm.h (smart_rename): Update prototype.
* rename.c (smart_rename): Add fromfd and preserve_dates params.
Pass fromfd and target_stat to simple_copy. Call set_times
when preserve_dates.
(simple_copy): Accept fromfd rather than from filename. Add
target_stat param. Rewind fromfd rather than opening. Open
"to" file without O_CREAT. Try to preserve S_ISUID and S_ISGID.
* ar.c (write_archive): Rename ofd to tmpfd. Dup tmpfd before
closing output temp file, and pass tmpfd to smart_rename.
* arsup.c (temp_fd): Rename from real_fd.
(ar_save): Dup temp_fd and pass to smart_rename.
* objcopy.c (strip_main, copy_main): Likewise, and pass
preserve_dates.
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r-- | binutils/objcopy.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/binutils/objcopy.c b/binutils/objcopy.c index abbcb7c..90ae0bd 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -4837,6 +4837,7 @@ strip_main (int argc, char *argv[]) struct stat statbuf; char *tmpname; int tmpfd = -1; + int copyfd = -1; if (get_file_size (argv[i]) < 1) { @@ -4846,7 +4847,11 @@ strip_main (int argc, char *argv[]) if (output_file == NULL || filename_cmp (argv[i], output_file) == 0) - tmpname = make_tempname (argv[i], &tmpfd); + { + tmpname = make_tempname (argv[i], &tmpfd); + if (tmpfd >= 0) + copyfd = dup (tmpfd); + } else tmpname = output_file; @@ -4864,14 +4869,18 @@ strip_main (int argc, char *argv[]) if (status == 0) { if (output_file != tmpname) - status = (smart_rename (tmpname, - output_file ? output_file : argv[i], - preserve_dates ? &statbuf : NULL) != 0); + status = smart_rename (tmpname, + output_file ? output_file : argv[i], + copyfd, &statbuf, preserve_dates) != 0; if (status == 0) status = hold_status; } else - unlink_if_ordinary (tmpname); + { + if (copyfd >= 0) + close (copyfd); + unlink_if_ordinary (tmpname); + } if (output_file != tmpname) free (tmpname); } @@ -5078,7 +5087,9 @@ copy_main (int argc, char *argv[]) bfd_boolean formats_info = FALSE; bfd_boolean use_globalize = FALSE; bfd_boolean use_keep_global = FALSE; - int c, tmpfd = -1; + int c; + int tmpfd = -1; + int copyfd; struct stat statbuf; const bfd_arch_info_type *input_arch = NULL; @@ -5916,10 +5927,15 @@ copy_main (int argc, char *argv[]) } /* If there is no destination file, or the source and destination files - are the same, then create a temp and rename the result into the input. */ + are the same, then create a temp and copy the result into the input. */ + copyfd = -1; if (output_filename == NULL || filename_cmp (input_filename, output_filename) == 0) - tmpname = make_tempname (input_filename, &tmpfd); + { + tmpname = make_tempname (input_filename, &tmpfd); + if (tmpfd >= 0) + copyfd = dup (tmpfd); + } else tmpname = output_filename; @@ -5934,11 +5950,15 @@ copy_main (int argc, char *argv[]) if (status == 0) { if (tmpname != output_filename) - status = (smart_rename (tmpname, input_filename, - preserve_dates ? &statbuf : NULL) != 0); + status = smart_rename (tmpname, input_filename, copyfd, + &statbuf, preserve_dates) != 0; } else - unlink_if_ordinary (tmpname); + { + if (copyfd >= 0) + close (copyfd); + unlink_if_ordinary (tmpname); + } if (tmpname != output_filename) free (tmpname); |