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.