diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f24c3f3b1..def2b3072 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +Fri Jun 1 13:45:00 2001 Corinna Vinschen + + * syscalls.cc (_rename): Handle the case that `foo' is renamed to + `bar' while `bar.lnk' is an existing shortcut-symlink. + Thu May 31 15:57:57 2001 Christopher Faylor * fhandler.cc (fhandler_disk_file::fstat): Avoid clearing S_IFMT bits diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 98df195f9..0a59e730b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1228,6 +1228,7 @@ _rename (const char *oldpath, const char *newpath) { sigframe thisframe (mainthread); int res = 0; + char *lnk_suffix = NULL; path_conv real_old (oldpath, PC_SYM_NOFOLLOW); @@ -1276,13 +1277,18 @@ _rename (const char *oldpath, const char *newpath) return (-1); } + /* Destination file exists and is read only, change that or else + the rename won't work. */ if (real_new.file_attributes () != (DWORD) -1 && real_new.file_attributes () & FILE_ATTRIBUTE_READONLY) - { - /* Destination file exists and is read only, change that or else - the rename won't work. */ - SetFileAttributesA (real_new.get_win32 (), real_new.file_attributes () & ~ FILE_ATTRIBUTE_READONLY); - } + SetFileAttributesA (real_new.get_win32 (), + real_new.file_attributes () & ~FILE_ATTRIBUTE_READONLY); + + /* Shortcut hack No. 2, part 1 */ + if (!real_old.issymlink () && !real_new.error && real_new.issymlink () && + real_new.known_suffix && strcasematch (real_new.known_suffix, ".lnk") && + (lnk_suffix = strrchr (real_new.get_win32 (), '.'))) + *lnk_suffix = '\0'; if (!MoveFile (real_old.get_win32 (), real_new.get_win32 ())) res = -1; @@ -1322,12 +1328,26 @@ _rename (const char *oldpath, const char *newpath) done: if (res) - __seterrno (); - - if (res == 0) + { + __seterrno (); + /* Reset R/O attributes if neccessary. */ + if (real_new.file_attributes () != (DWORD) -1 && + real_new.file_attributes () & FILE_ATTRIBUTE_READONLY) + SetFileAttributesA (real_new.get_win32 (), real_new.file_attributes ()); + } + else { /* make the new file have the permissions of the old one */ SetFileAttributesA (real_new.get_win32 (), real_old.file_attributes ()); + + /* Shortcut hack, No. 2, part 2 */ + /* if the new filename was an existing shortcut, remove it now if the + new filename is equal to the shortcut name without .lnk suffix. */ + if (lnk_suffix) + { + *lnk_suffix = '.'; + DeleteFile (real_new.get_win32 ()); + } } syscall_printf ("%d = rename (%s, %s)", res, real_old.get_win32 (),