diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 02641f337..fe91bffa2 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -324,9 +324,18 @@ path_conv::check (const char *src, unsigned opt, if (sym.case_clash) { - case_clash = TRUE; - error = ENOENT; - goto out; + if (pcheck_case == PCHECK_STRICT) + { + case_clash = TRUE; + error = ENOENT; + goto out; + } + /* If pcheck_case==PCHECK_ADJUST the case_clash is remembered + if the last component is concerned. This allows functions + which shall create files to avoid overriding already existing + files with another case. */ + if (!component) + case_clash = TRUE; } if (!(opt & PC_SYM_IGNORE)) @@ -2754,13 +2763,12 @@ symlink_info::case_check (const char *path, char *orig_path) /* If that part of the component exists, check the case. */ if (strcmp (c, data.cFileName)) { + case_clash = TRUE; + /* If check is set to STRICT, a wrong case results in returning a ENOENT. */ if (pcheck_case == PCHECK_STRICT) - { - case_clash = TRUE; - return FALSE; - } + return FALSE; /* PCHECK_ADJUST adjusts the case in the incoming path which points to the path in *this. */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 933baafcf..5a9b24c0f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1246,7 +1246,7 @@ _rename (const char *oldpath, const char *newpath) /* Shortcut hack. */ char new_lnk_buf[MAX_PATH + 5]; - if (real_old.issymlink () && !real_new.error) + if (real_old.issymlink () && !real_new.error && !real_new.case_clash) { int len_old = strlen (real_old.get_win32 ()); if (strcasematch (real_old.get_win32 () + len_old - 4, ".lnk")) @@ -1258,10 +1258,10 @@ _rename (const char *oldpath, const char *newpath) } } - if (real_new.error) + if (real_new.error || real_new.case_clash) { syscall_printf ("-1 = rename (%s, %s)", oldpath, newpath); - set_errno (real_new.error); + set_errno (real_new.case_clash ? ECASECLASH : real_new.error); return -1; }