On Thu, Mar 15, 2012 at 5:02 PM, Benjamin Fritz <[email protected]>wrote:
> On Thu, Mar 15, 2012 at 2:28 PM, Bram Moolenaar <[email protected]> > wrote: > > > > David Pope wrote: > > > >> On Wednesday, July 20, 2011 3:54:09 PM UTC-4, Craig Barkhouse wrote: > >> > >> > The mch_is_linked() function in os_win32.c only checks if there is > >> > more than one hard link (i.e. name) for the file. It doesn't check > >> > if the file is a symbolic link. By contrast the Unix code does > >> > check if the file is a symbolic link. > >> > > >> > Sounds like a TODO item. > >> > >> Hello all, did this ever get turned into a TODO item? I've > >> encountered this myself (I'm syncing all my vim configuration across > >> machines using Dropbox, with symbolic links for .vim/, .vimrc, and > >> .gvimrc). > >> > >> I see in the latest Mercurial code that mch_is_linked() still only > >> checks for hard links. If it's not already in someone's TODO bucket I > >> can work on a fix. The APIs are straightforward in the versions of > >> Windows that support symlinks; I suspect more of the work will be in > >> figuring out how to get that support into vim without breaking binary > >> compatibility on older systems. Would the maintainers be interested > >> in seeing a patch for this? > > > > A patch definitely helps. And a way to reproduce the problem. > > > > Reproduction is easy. > > 1. Create a symbolic link on Windows. (e.g. mklink link_path target_path) > 2. open the file in Vim > 3. write the file from Vim > > The symbolic link has been destroyed, now it's a "real" file separate > from the file it was originally linked to. Here's my first shot at a patch that fixes the "can't save to symlinks" bug on Windows. It augments the Windows version of mch_is_linked() to also return TRUE if the file is a symbolic link, so the delete-then-move pattern is avoided and the symlink is preserved. The patch also addresses a separate bug I encountered while fixing the above. If you set nowritebackup on Windows, and then save a file that you opened via a symbolic link, the readonly attribute gets set. The cause was that the Windows version of mch_getperm() was returning Windows FILE_ATTRIBUTE_* flags instead of the Unix-style flags in mode_t, which was then later passed unchanged to the CRT open() function (which expects mode_t flags). For a normal (non-symlink, non-whatever) file, this just happened to be FILE_ATTRIBUTE_NORMAL (0200, 0x80), which maps to the Unix S_IWUSR. By sheer chance, this meant that normal files correctly received write permission, i.e. no readonly flag. For a symlink, FILE_ATTRIBUTE_NORMAL is not set; for example, the symlink I was testing against returned FILE_ATTRIBUTE_ARCHIVE (040, 0x20) and FILE_ATTRIBUTE_REPARSE_POINT (02000, 0x400). By the time these made it back to create(), it appeared as though we wanted no write permissions, i.e. set the readonly flag. The patch changes os_win32.c so that all code outside of the file deals with mode_t flags, while os_win32.c itself deals with FILE_ATTRIBUTE_* flags. There are a couple of new internal helper functions for this. This is my first patch, so I'm sure I messed up somewhere; feedback is welcome. Sorry if the above is too wordy, this was a fun one to diagnose. ;) Caveats: * I have no way to test Win98, can someone help? There is lots of Win98 fallback code in os_win32.c (to use non-Unicode functions when FEAT_MBYTE is defined). * I added win32_* signatures to os_win32.pro for the new internal functions; I'm not sure if the *.pro files are intended mainly for function exports, or just to avoid having to make forward declarations (as I've done here). * I'm using a couple of CRT functions that weren't in use before; I don't know if it's reasonable to assume that they work as expected on all the old platforms that are required. ---- David Pope -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php
symlinkfix.diff
Description: Binary data
