Warn when the plugin interface runs out of file descriptors.
authorNick Clifton <nickc@redhat.com>
Wed, 19 May 2021 10:53:23 +0000 (11:53 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 19 May 2021 10:53:23 +0000 (11:53 +0100)
* plugin.c (bfd_plugin_open_input): Inform the user if the limit
on the number of open files is reached.  If possible, try to
increase this limit before failing.

bfd/ChangeLog
bfd/plugin.c

index b399aefd120efcfa7e5ef3e5a946156ab26ddf31..a389fdfc8b182e9c9ccd97a48ea7dd512daebae2 100644 (file)
@@ -1,3 +1,9 @@
+2021-05-19  Nick Clifton  <nickc@redhat.com>
+
+       * plugin.c (bfd_plugin_open_input): Inform the user if the limit
+       on the number of open files is reached.  If possible, try to
+       increase this limit before failing.
+
 2021-05-14  Nelson Chu  <nelson.chu@sifive.com>
 
        * elfnn-riscv.c (riscv_resolve_pcrel_lo_relocs): Check the values
index c4f2be8999e227276b2605f081cd4d036fe9fe31..1fee4d0c87003012dac38d627fe52123d0838d9d 100644 (file)
@@ -209,7 +209,35 @@ bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file)
      the same underlying file descriptor.  */
   file->fd = open (file->name, O_RDONLY | O_BINARY);
   if (file->fd < 0)
-    return 0;
+    {
+#ifndef EMFILE
+      return 0;
+#else
+      if (errno != EMFILE)
+       return 0;
+
+#ifdef HAVE_GETRLIMIT
+      struct rlimit lim;
+
+      /* Complicated links involving lots of files and/or large archives
+        can exhaust the number of file descriptors available to us.
+        If possible, try to allocate more descriptors.  */
+      if (getrlimit (RLIMIT_NOFILE, & lim) == 0
+         && lim.rlim_cur < lim.rlim_max)
+       {
+         lim.rlim_cur = lim.rlim_max;
+         if (setrlimit (RLIMIT_NOFILE, &lim) == 0)
+           file->fd = open (file->name, O_RDONLY | O_BINARY);
+       }
+
+      if (file->fd < 0)
+#endif
+       {
+         _bfd_error_handler (_("plugin framework: out of file descriptors. Try using fewer objects/archives\n"));
+         return 0;
+       } 
+#endif
+   }
 
   if (iobfd == ibfd)
     {