return bfd_fopen (filename, target, mode, fd);
 }
 
+/*
+FUNCTION
+       bfd_fdopenw
+
+SYNOPSIS
+       bfd *bfd_fdopenw (const char *filename, const char *target, int fd);
+
+DESCRIPTION
+       <<bfd_fdopenw>> is exactly like <<bfd_fdopenr>> with the exception that
+       the resulting BFD is suitable for output.
+*/
+
+bfd *
+bfd_fdopenw (const char *filename, const char *target, int fd)
+{
+  bfd *out = bfd_fdopenr (filename, target, fd);
+
+  if (out != NULL)
+    {
+      if (!bfd_write_p (out))
+       {
+         close (fd);
+         _bfd_delete_bfd (out);
+         out = NULL;
+         bfd_set_error (bfd_error_invalid_operation);
+       }
+      else
+       out->direction = write_direction;
+    }
+
+  return out;
+}
+
 /*
 FUNCTION
        bfd_openstreamr
 
+2020-12-07  Siddhesh Poyarekar  <siddhesh@sourceware.org>
+
+       PR 26945
+       * bucomm.c (make_tempname): Add argument to return file
+       descriptor.
+       * bucomm.h (make_tempname): Likewise.
+       * ar.c: Include libbfd.h.
+       (write_archive): Adjust for change in make_tempname.  Call
+       bfd_fdopenw instead of bfd_openw.
+       * objcopy.c: Include libbfd.h.
+       (copy_file): New argument OFD.  Use bfd_fdopenw instead of
+       bfd_openw.
+       (strip_main): Adjust for change in make_tempname and
+       copy_file.
+       (copy_main): Likewise.
+
+
 2020-12-07  Nick Clifton  <nickc@redhat.com>
 
        * README-how-to-make-a-release (point releases): Add a note to
 
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "libbfd.h"
 #include "libiberty.h"
 #include "progress.h"
 #include "getopt.h"
   bfd *obfd;
   char *old_name, *new_name;
   bfd *contents_head = iarch->archive_next;
+  int ofd = -1;
 
   old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
   strcpy (old_name, bfd_get_filename (iarch));
-  new_name = make_tempname (old_name);
+  new_name = make_tempname (old_name, &ofd);
 
   if (new_name == NULL)
     bfd_fatal (_("could not create temporary file whilst writing archive"));
 
   output_filename = new_name;
 
-  obfd = bfd_openw (new_name, bfd_get_target (iarch));
+  obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), ofd);
 
   if (obfd == NULL)
-    bfd_fatal (old_name);
+    {
+      close (ofd);
+      bfd_fatal (old_name);
+    }
 
   output_bfd = obfd;
 
 
 \f
 #include "sysdep.h"
 #include "bfd.h"
+#include "libbfd.h"
 #include "progress.h"
 #include "getopt.h"
 #include "libiberty.h"
 /* The top-level control.  */
 
 static void
-copy_file (const char *input_filename, const char *output_filename,
+copy_file (const char *input_filename, const char *output_filename, int ofd,
           const char *input_target,   const char *output_target,
           const bfd_arch_info_type *input_arch)
 {
       else
        force_output_target = TRUE;
 
-      obfd = bfd_openw (output_filename, output_target);
+      if (ofd >= 0)
+       obfd = bfd_fdopenw (output_filename, output_target, ofd);
+      else
+       obfd = bfd_openw (output_filename, output_target);
+
       if (obfd == NULL)
        {
+         close (ofd);
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
          status = 1;
          return;
       if (output_target == NULL)
        output_target = bfd_get_target (ibfd);
 
-      obfd = bfd_openw (output_filename, output_target);
+      if (ofd >= 0)
+       obfd = bfd_fdopenw (output_filename, output_target, ofd);
+      else
+       obfd = bfd_openw (output_filename, output_target);
+
       if (obfd == NULL)
        {
+         close (ofd);
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
          status = 1;
          return;
        }
+
       /* This is a no-op on non-Coff targets.  */
       set_long_section_mode (obfd, ibfd, long_section_names);
 
       int hold_status = status;
       struct stat statbuf;
       char *tmpname;
+      int tmpfd = -1;
 
       if (get_file_size (argv[i]) < 1)
        {
 
       if (output_file == NULL
          || filename_cmp (argv[i], output_file) == 0)
-       tmpname = make_tempname (argv[i]);
+       tmpname = make_tempname (argv[i], &tmpfd);
       else
        tmpname = output_file;
 
        }
 
       status = 0;
-      copy_file (argv[i], tmpname, input_target, output_target, NULL);
+      copy_file (argv[i], tmpname, tmpfd, input_target, output_target, NULL);
       if (status == 0)
        {
          if (preserve_dates)
   bfd_boolean formats_info = FALSE;
   bfd_boolean use_globalize = FALSE;
   bfd_boolean use_keep_global = FALSE;
-  int c;
+  int c, tmpfd = -1;
   struct stat statbuf;
   const bfd_arch_info_type *input_arch = NULL;
 
      are the same, then create a temp and rename the result into the input.  */
   if (output_filename == NULL
       || filename_cmp (input_filename, output_filename) == 0)
-    tmpname = make_tempname (input_filename);
+    tmpname = make_tempname (input_filename, &tmpfd);
   else
     tmpname = output_filename;
 
     fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
           input_filename, strerror (errno));
 
-  copy_file (input_filename, tmpname, input_target, output_target, input_arch);
+  copy_file (input_filename, tmpname, tmpfd, input_target, output_target,
+            input_arch);
   if (status == 0)
     {
       if (preserve_dates)