Add code to the BFD library to handle opening files with pathnames longer than MAX_PA...
authorNick Clifton <nickc@redhat.com>
Tue, 24 Mar 2020 15:24:02 +0000 (15:24 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 24 Mar 2020 15:24:02 +0000 (15:24 +0000)
PR 25713
* bfdio.c (_bfd_real_fopen): Add code to handle long filenames on
Win32 systems.

bfd/ChangeLog
bfd/bfdio.c

index d9e1139eb1a5bba9945632aa1ffef5cf84e3b77c..93c4bf950e61726d2866aeed8408ef75ec48a417 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-24  Nick Clifton  <nickc@redhat.com>
+
+       PR 25713
+       * bfdio.c (_bfd_real_fopen): Add code to handle long filenames on
+       Win32 systems.
+
 2020-03-24  Nick Clifton  <nickc@redhat.com>
 
        PR 25681
index 71ac17ec51515e157214769d8efb5fc45971d3df..9e88f5be9150fda1d8ff3bd83ab17f165350d884 100644 (file)
@@ -26,6 +26,9 @@
 #include "bfd.h"
 #include "libbfd.h"
 #include "aout/ar.h"
+#if defined (_WIN32)
+#include <windows.h>
+#endif
 
 #ifndef S_IXUSR
 #define S_IXUSR 0100    /* Execute by owner.  */
@@ -93,12 +96,7 @@ _bfd_real_fopen (const char *filename, const char *modes)
      In fopen-vms.h, they are separated from the mode with a comma.
      Split here.  */
   vms_attr = strchr (modes, ',');
-  if (vms_attr == NULL)
-    {
-      /* No attributes.  */
-      return close_on_exec (fopen (filename, modes));
-    }
-  else
+  if (vms_attr != NULL)
     {
       /* Attributes found.  Split.  */
       size_t modes_len = strlen (modes) + 1;
@@ -116,13 +114,29 @@ _bfd_real_fopen (const char *filename, const char *modes)
        }
       return close_on_exec (fopen (filename, at[0], at[1], at[2]));
     }
-#else /* !VMS */
-#if defined (HAVE_FOPEN64)
+
+#elif defined (_WIN32)
+  size_t filelen = strlen (filename) + 1;
+
+  if (filelen > MAX_PATH - 1)
+    {
+      FILE *file;
+      char* fullpath = (char *) malloc (filelen + 8);
+
+      /* Add a Microsoft recommended prefix that
+        will allow the extra-long path to work.  */
+      strcpy (fullpath, "\\\\?\\");
+      strcat (fullpath, filename);
+      file = close_on_exec (fopen (fullpath, modes));
+      free (fullpath);
+      return file;
+    }
+
+#elif defined (HAVE_FOPEN64)
   return close_on_exec (fopen64 (filename, modes));
-#else
-  return close_on_exec (fopen (filename, modes));
 #endif
-#endif /* !VMS */
+
+  return close_on_exec (fopen (filename, modes));
 }
 
 /*