diff --git a/winsup/cygwin/msys2_path_conv.cc b/winsup/cygwin/msys2_path_conv.cc index 406b98ac81..646eef32c4 100644 --- a/winsup/cygwin/msys2_path_conv.cc +++ b/winsup/cygwin/msys2_path_conv.cc @@ -310,6 +310,10 @@ const char* convert(char *dst, size_t dstlen, const char *src) { } sub_convert(&srcbeg, &srcit, &dstit, dstend, &in_string); + if (!*srcit) { + *dstit = '\0'; + return dst; + } srcbeg = srcit + 1; for (; *srcit != '\0'; ++srcit) { continue; @@ -441,7 +445,7 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en return find_path_start_and_type(src, true, end); } - if (ch == ':') { + if (ch == ':' && it2 + 1 != end) { it2 += 1; ch = *it2; if (ch == '/' || ch == ':' || ch == '.') { @@ -536,7 +540,7 @@ void url_convert(const char** from, const char* to, char** dst, const char* dste void subp_convert(const char** from, const char* end, int is_url, char** dst, const char* dstend) { const char* begin = *from; - path_type type = find_path_start_and_type(from, 0, end); + path_type type = is_url ? URL : find_path_start_and_type(from, 0, end); copy_to_dst(begin, *from, dst, dstend); if (type == NONE) { @@ -566,9 +570,16 @@ void ppl_convert(const char** from, const char* to, char** dst, const char* dste if (prev_was_simc) { continue; } - if (*(it + 1) == '/' && *(it + 2) == '/') { + if (*(it + 1) == '/' && *(it + 2) == '/' && isalpha(*beg)) { is_url = 1; - continue; + /* double-check: protocol must be alnum (or +) */ + for (const char *p = beg; p != it; ++p) + if (!isalnum(*p) && *p != '+') { + is_url = 0; + break; + } + if (is_url) + continue; } prev_was_simc = 1; subp_convert(&beg, it, is_url, dst, dstend); @@ -613,7 +624,7 @@ void posix_to_win32_path(const char* from, const char* to, char** dst, const cha strncpy(one_path, from, to-from); one_path[to-from] = '\0'; - path_conv conv (one_path, 0); + path_conv conv (one_path, PC_KEEP_FINAL_SLASH); if (conv.error) { set_errno(conv.error); diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ad152e461a..f311a04962 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1236,9 +1236,22 @@ path_conv::check (const char *src, unsigned opt, cfree (wide_path); wide_path = NULL; } + + if (need_directory) + { + size_t n = strlen (this->path); + /* Do not add trailing \ to UNC device names like \\.\a: */ + if (this->path[n - 1] != '\\' && + (strncmp (this->path, "\\\\.\\", 4) != 0)) + { + this->modifiable_path ()[n] = '\\'; + this->modifiable_path ()[n + 1] = '\0'; + } + need_directory = 0; + } } - if (need_directory) + if ((opt & PC_KEEP_FINAL_SLASH) && need_directory) { size_t n = strlen (this->path); /* Do not add trailing \ to UNC device names like \\.\a: */ @@ -1248,6 +1261,7 @@ path_conv::check (const char *src, unsigned opt, this->modifiable_path ()[n] = '\\'; this->modifiable_path ()[n + 1] = '\0'; } + need_directory = 0; } if (opt & PC_OPEN) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 0c94c61522..69a78bcbca 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -58,6 +58,7 @@ enum pathconv_arg PC_SYM_NOFOLLOW_PROCFD = _BIT (11), PC_KEEP_HANDLE = _BIT (12), PC_NO_ACCESS_CHECK = _BIT (13), + PC_KEEP_FINAL_SLASH = _BIT (14), PC_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 17d532bc02..240777b757 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -327,7 +327,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) } else { - /* Create unique filename. Start with a dot, followed by "cyg" + /* Create unique filename. Start with a dot, followed by "msys" transposed into the Unicode low surrogate area (U+dc00) on file systems supporting Unicode (except Samba), followed by the inode number in hex, followed by a path hash in hex. The combination @@ -335,7 +335,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) RtlAppendUnicodeToString (&recycler, (pc.fs_flags () & FILE_UNICODE_ON_DISK && !pc.fs_is_samba ()) - ? L".\xdc73\xdc6d\xdc79\xdc6d" : L".msys"); + ? L".\xdc6d\xdc73\xdc79\xdc73" : L".msys"); pfii = (PFILE_INTERNAL_INFORMATION) infobuf; status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, FileInternalInformation); diff --git a/winsup/utils/strace.cc b/winsup/utils/strace.cc index 6c94158f3d..e7291bbc8d 100644 --- a/winsup/utils/strace.cc +++ b/winsup/utils/strace.cc @@ -351,7 +351,8 @@ create_child (char **argv) flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP; make_command_line (one_line, argv); - printf ("create_child: %s\n", one_line.buf); + if (!quiet) + printf ("create_child: %s\n", one_line.buf); SetConsoleCtrlHandler (NULL, 0); /* Commit message for this code was: