[PATCH] Reopen output file when writing archive output [BZ #27270][BZ #27284]

Siddhesh Poyarekar siddhesh@gotplt.org
Mon Feb 1 05:32:30 GMT 2021


When saving an archive, the archive stream could have got closed due
to there being too many open files in the BFD cache, so the stream
being NULL does not indicate that the file does not exist.  Instead,
attempt to reopen the stream.

binutils/

	[BZ #27270]
	[BZ #27284]
	* ar.c (write_archive): Remove unnecessary NULL check for
	IARCH and try to reopen the archive stream.
	* arsup.c: Include libbfd.h.
	(ar_save): Attempt to reopen the archive stream.
---
 binutils/ar.c    | 2 +-
 binutils/arsup.c | 9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/binutils/ar.c b/binutils/ar.c
index 24ff0920f40..9644942ac24 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1303,7 +1303,7 @@ write_archive (bfd *iarch)
 
 #if !defined (_WIN32) || defined (__CYGWIN32__)
   ofd = dup (ofd);
-  if (iarch == NULL || iarch->iostream == NULL)
+  if (iarch->iostream == NULL && bfd_open_file (iarch) == NULL)
     skip_stat = TRUE;
   else if (ofd == -1 || fstat (fileno ((FILE *) iarch->iostream), &target_stat) != 0)
     bfd_fatal (old_name);
diff --git a/binutils/arsup.c b/binutils/arsup.c
index 837011bdfd2..b305c753f73 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -27,6 +27,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "libbfd.h"
 #include "libiberty.h"
 #include "filenames.h"
 #include "bucomm.h"
@@ -353,9 +354,11 @@ ar_save (void)
         obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
 
 #if !defined (_WIN32) || defined (__CYGWIN32__)
-      /* It's OK to fail; at worst it will result in SMART_RENAME using a slow
-         copy fallback to write the output.  */
-      ofd = dup (fileno ((FILE *) obfd->iostream));
+      /* Try to reopen the output BFD stream if it has closed.  It's OK for DUP
+	 to fail; at worst it will result in SMART_RENAME using a slow copy
+	 fallback to write the output.  */
+      if (obfd->iostream != NULL || bfd_open_file (obfd) != NULL)
+	ofd = dup (fileno ((FILE *) obfd->iostream));
       if (lstat (real_name, &target_stat) != 0)
 	skip_stat = TRUE;
 #endif
-- 
2.29.2



More information about the Binutils mailing list