diff options
author | Tom Tromey <tom@tromey.com> | 2018-09-20 16:30:47 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-10-27 11:58:41 -0600 |
commit | 36033ef57cd048588f9a3d5523712147066421f2 (patch) | |
tree | c5e9a94e4f5eb6b7c4bd50fe3baf53cd52eee73f /gdb/dwarf-index-write.c | |
parent | Use mkostemp, not mkstemp (diff) | |
download | binutils-gdb-36033ef57cd048588f9a3d5523712147066421f2.tar.gz binutils-gdb-36033ef57cd048588f9a3d5523712147066421f2.tar.bz2 binutils-gdb-36033ef57cd048588f9a3d5523712147066421f2.zip |
Do not reopen temporary files
The current callers of mkostemp close the file descriptor and then
re-open it with fopen. It seemed better to me to continue to use the
already-opened file descriptor, so this patch rearranges the code a
little in order to do so. It takes care to ensure that the files are
only unlinked after the file descriptor in question is closed, as
before.
gdb/ChangeLog
2018-10-27 Tom Tromey <tom@tromey.com>
* unittests/scoped_fd-selftests.c (test_to_file): New function.
(run_tests): Call test_to_file.
* dwarf-index-write.c (write_psymtabs_to_index): Do not reopen
temporary files.
* common/scoped_fd.h (scoped_fd::to_file): New method.
Diffstat (limited to 'gdb/dwarf-index-write.c')
-rw-r--r-- | gdb/dwarf-index-write.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/gdb/dwarf-index-write.c b/gdb/dwarf-index-write.c index e07bda9c08b..8a4c1c7ea4b 100644 --- a/gdb/dwarf-index-write.c +++ b/gdb/dwarf-index-write.c @@ -1566,23 +1566,21 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile, ? INDEX5_SUFFIX : INDEX4_SUFFIX)); gdb::char_vector filename_temp = make_temp_filename (filename); - gdb::optional<scoped_fd> out_file_fd - (gdb::in_place, gdb_mkostemp_cloexec (filename_temp.data (), O_BINARY)); - if (out_file_fd->get () == -1) + /* Order matters here; we want FILE to be closed before + FILENAME_TEMP is unlinked, because on MS-Windows one cannot + delete a file that is still open. So, we wrap the unlinker in an + optional and emplace it once we know the file name. */ + gdb::optional<gdb::unlinker> unlink_file; + scoped_fd out_file_fd (gdb_mkostemp_cloexec (filename_temp.data (), + O_BINARY)); + if (out_file_fd.get () == -1) perror_with_name (("mkstemp")); - FILE *out_file = gdb_fopen_cloexec (filename_temp.data (), "wb").release (); + gdb_file_up out_file = out_file_fd.to_file ("wb"); if (out_file == nullptr) error (_("Can't open `%s' for writing"), filename_temp.data ()); - /* Order matters here; we want FILE to be closed before FILENAME_TEMP is - unlinked, because on MS-Windows one cannot delete a file that is - still open. (Don't call anything here that might throw until - file_closer is created.) We don't need OUT_FILE_FD anymore, so we might - as well close it now. */ - out_file_fd.reset (); - gdb::unlinker unlink_file (filename_temp.data ()); - gdb_file_up close_out_file (out_file); + unlink_file.emplace (filename_temp.data ()); if (index_kind == dw_index_kind::DEBUG_NAMES) { @@ -1590,45 +1588,45 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile, + basename + DEBUG_STR_SUFFIX); gdb::char_vector filename_str_temp = make_temp_filename (filename_str); - gdb::optional<scoped_fd> out_file_str_fd - (gdb::in_place, gdb_mkostemp_cloexec (filename_str_temp.data (), - O_BINARY)); - if (out_file_str_fd->get () == -1) + /* As above, arrange to unlink the file only after the file + descriptor has been closed. */ + gdb::optional<gdb::unlinker> unlink_file_str; + scoped_fd out_file_str_fd + (gdb_mkostemp_cloexec (filename_str_temp.data (), O_BINARY)); + if (out_file_str_fd.get () == -1) perror_with_name (("mkstemp")); - FILE *out_file_str - = gdb_fopen_cloexec (filename_str_temp.data (), "wb").release (); + gdb_file_up out_file_str = out_file_str_fd.to_file ("wb"); if (out_file_str == nullptr) error (_("Can't open `%s' for writing"), filename_str_temp.data ()); - out_file_str_fd.reset (); - gdb::unlinker unlink_file_str (filename_str_temp.data ()); - gdb_file_up close_out_file_str (out_file_str); + unlink_file_str.emplace (filename_str_temp.data ()); const size_t total_len - = write_debug_names (dwarf2_per_objfile, out_file, out_file_str); - assert_file_size (out_file, filename_temp.data (), total_len); + = write_debug_names (dwarf2_per_objfile, out_file.get (), + out_file_str.get ()); + assert_file_size (out_file.get (), filename_temp.data (), total_len); /* We want to keep the file .debug_str file too. */ - unlink_file_str.keep (); + unlink_file_str->keep (); /* Close and move the str file in place. */ - close_out_file_str.reset (); + out_file_str.reset (); if (rename (filename_str_temp.data (), filename_str.c_str ()) != 0) perror_with_name (("rename")); } else { const size_t total_len - = write_gdbindex (dwarf2_per_objfile, out_file); - assert_file_size (out_file, filename_temp.data (), total_len); + = write_gdbindex (dwarf2_per_objfile, out_file.get ()); + assert_file_size (out_file.get (), filename_temp.data (), total_len); } /* We want to keep the file. */ - unlink_file.keep (); + unlink_file->keep (); /* Close and move the file in place. */ - close_out_file.reset (); + out_file.reset (); if (rename (filename_temp.data (), filename.c_str ()) != 0) perror_with_name (("rename")); } |