bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/25713] Linker(ld.exe) runs in Windows unable to find file if pat


From: fredrick.eisele at gmail dot com
Subject: [Bug ld/25713] Linker(ld.exe) runs in Windows unable to find file if path length is more than 260 characters.
Date: Wed, 16 Feb 2022 20:07:01 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=25713

--- Comment #26 from Fred Eisele <fredrick.eisele at gmail dot com> ---
Some tweaks needed to me made to get the _fopen() to work properly.

#include <stdio.h>
#include <errno.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>

/* Mark FILE as close-on-exec.  Return FILE.  FILE may be NULL, in
   which case nothing is done.  */
static FILE *
close_on_exec(FILE *file) {
#if defined (HAVE_FILENO) && defined (F_GETFD)
  if (file)
    {
      int fd = fileno (file);
      int old = fcntl (fd, F_GETFD, 0);
      if (old >= 0)
  fcntl (fd, F_SETFD, old | FD_CLOEXEC);
    }
#endif
  return file;
}

/**
 *
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
 *
https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
 * @return
 */
int main() {
  wchar_t **lpFilePart = {NULL};
  const wchar_t prefix[] = L"\\\\?\\";
  const char *paths[] = {
      "C:\\tools\\foo.o",
      "C:\\tools\\.\\foo.o",
      "C:\\tools\\msys64\\..\\foo.o",
      ".\\foo.o",
      ".\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\test.o",
      ".\\increasepath\\increasepath\\.\\.\\increasepath\\increasepath\\"
     
"increasepath\\increasepath\\..\\..\\increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\increasepath\\increasepath\\increasepath\\"
      "increasepath\\increasepath\\test.o"
  };
  setbuf(stderr, NULL);
  int loopLimit = sizeof(paths) / sizeof(*paths);
  for (int ix = 0; ix < loopLimit; ix++) {
    const char *filename = paths[ix];
    const char modes[] = "w+b";
    FILE *file;

    fprintf(stderr, "====================================================\n");

    /* PR 25713: Handle extra long path names possibly containing '..' and '.'.
*/
    wchar_t **lpFilePart = {NULL};
    const char ccs[] = ", ccs=UNICODE";
    const int partPathLen = strlen(filename) + 1;
    char *partPathOrig = calloc(partPathLen, sizeof(char));
    /*
     * Convert any UNIX style path separators into the DOS form.
     */
    int ix;
    for (ix = 0; ix < partPathLen; ix++)
      switch (filename[ix]) {
        case '/':
          partPathOrig[ix] = '\\';
          break;
        default:
          partPathOrig[ix] = filename[ix];
      }
    partPathOrig[ix] = 0;
    fprintf(stderr, "part: path = %s\n", partPathOrig);
    /*
     * Converting from the partial path from ascii to unicode.
     * Calling with lpWideCharStr set to null returns the length.
     * Calling with cbMultiByte set to -1 includes the terminating null.
     */
    int partPathWSize = MultiByteToWideChar(CP_UTF8, 0, partPathOrig, -1, NULL,
0);
    wchar_t *partPath = calloc(partPathWSize, sizeof(wchar_t));
    MultiByteToWideChar(CP_UTF8, 0, partPathOrig, -1, partPath, partPathWSize);
    fprintf(stderr, "part: wpath = %ls\n", partPath);
    /*
     * Getting the full path from the provided partial path.
     * Calling twice: 1) get the length; 2) resolve the path.
     */
    long fullPathWSize = GetFullPathNameW(partPath, 0, NULL, lpFilePart);
    wchar_t *fullPathTmp = calloc(fullPathWSize, sizeof(wchar_t));
    long copiedPathLen = GetFullPathNameW(partPath, fullPathWSize, fullPathTmp,
lpFilePart);
    fprintf(stderr, "full: errno = %d error = %s\n", errno, strerror(errno));
    wchar_t *fullPath = calloc(fullPathWSize + sizeof(prefix),
sizeof(wchar_t));
    wcscpy(fullPath, prefix);
    wcscat(fullPath, fullPathTmp);
    free(partPath);

    int remodelSize = strlen(modes) + sizeof(ccs) + 1;
    char *remode = calloc(remodelSize, sizeof(char));
    strcpy(remode, modes);
    strcat(remode, ccs);
    wchar_t* remodel = calloc(remodelSize, sizeof(wchar_t));
    MultiByteToWideChar(CP_UTF8, 0, remode, -1, remodel, remodelSize);
    free(remode);

    fprintf(stderr, "file: mode  = %ls, fullPath = %ls\n", remodel, fullPath,
remodel);
    file = _wfopen(fullPath, remodel);
    fprintf(stderr, "file: errno = %d error = %s\n", errno, strerror(errno));
    free(remodel);
    file = close_on_exec(file);

    free(fullPath);
  }

  return 0;
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]