Loading ...
Sorry, an error occurred while loading the content.

Patch 7.4.039

Expand Messages
  • Bram Moolenaar
    Patch 7.4.039 Problem: MS-Windows: MSCV10 and earlier can t handle symlinks to a directory properly. Solution: Add stat_symlink_aware() and
    Message 1 of 1 , Sep 25, 2013
    • 0 Attachment
      Patch 7.4.039
      Problem: MS-Windows: MSCV10 and earlier can't handle symlinks to a
      directory properly.
      Solution: Add stat_symlink_aware() and wstat_symlink_aware(). (Ken Takata)
      Files: src/os_mswin.c, src/os_win32.c, src/os_win32.h


      *** ../vim-7.4.038/src/os_mswin.c 2013-08-30 16:51:15.000000000 +0200
      --- src/os_mswin.c 2013-09-25 19:09:53.000000000 +0200
      ***************
      *** 498,503 ****
      --- 498,595 ----
      }
      }

      + static int
      + stat_symlink_aware(const char *name, struct stat *stp)
      + {
      + #if defined(_MSC_VER) && _MSC_VER < 1700
      + /* Work around for VC10 or earlier. stat() can't handle symlinks properly.
      + * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves
      + * status of a symlink itself.
      + * VC10: stat() supports a symlink to a normal file, but it doesn't support
      + * a symlink to a directory (always returns an error). */
      + WIN32_FIND_DATA findData;
      + HANDLE hFind, h;
      + DWORD attr = 0;
      + BOOL is_symlink = FALSE;
      +
      + hFind = FindFirstFile(name, &findData);
      + if (hFind != INVALID_HANDLE_VALUE)
      + {
      + attr = findData.dwFileAttributes;
      + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
      + && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
      + is_symlink = TRUE;
      + FindClose(hFind);
      + }
      + if (is_symlink)
      + {
      + h = CreateFile(name, FILE_READ_ATTRIBUTES,
      + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
      + OPEN_EXISTING,
      + (attr & FILE_ATTRIBUTE_DIRECTORY)
      + ? FILE_FLAG_BACKUP_SEMANTICS : 0,
      + NULL);
      + if (h != INVALID_HANDLE_VALUE)
      + {
      + int fd, n;
      +
      + fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
      + n = _fstat(fd, (struct _stat*)stp);
      + _close(fd);
      + return n;
      + }
      + }
      + #endif
      + return stat(name, stp);
      + }
      +
      + #ifdef FEAT_MBYTE
      + static int
      + wstat_symlink_aware(const WCHAR *name, struct _stat *stp)
      + {
      + # if defined(_MSC_VER) && _MSC_VER < 1700
      + /* Work around for VC10 or earlier. _wstat() can't handle symlinks properly.
      + * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves
      + * status of a symlink itself.
      + * VC10: _wstat() supports a symlink to a normal file, but it doesn't
      + * support a symlink to a directory (always returns an error). */
      + int n;
      + BOOL is_symlink = FALSE;
      + HANDLE hFind, h;
      + DWORD attr = 0;
      + WIN32_FIND_DATAW findDataW;
      +
      + hFind = FindFirstFileW(name, &findDataW);
      + if (hFind != INVALID_HANDLE_VALUE)
      + {
      + attr = findDataW.dwFileAttributes;
      + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT)
      + && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
      + is_symlink = TRUE;
      + FindClose(hFind);
      + }
      + if (is_symlink)
      + {
      + h = CreateFileW(name, FILE_READ_ATTRIBUTES,
      + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
      + OPEN_EXISTING,
      + (attr & FILE_ATTRIBUTE_DIRECTORY)
      + ? FILE_FLAG_BACKUP_SEMANTICS : 0,
      + NULL);
      + if (h != INVALID_HANDLE_VALUE)
      + {
      + int fd;
      +
      + fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
      + n = _fstat(fd, stp);
      + _close(fd);
      + return n;
      + }
      + }
      + # endif
      + return _wstat(name, stp);
      + }
      + #endif

      /*
      * stat() can't handle a trailing '/' or '\', remove it first.
      ***************
      *** 534,540 ****

      if (wp != NULL)
      {
      ! n = _wstat(wp, (struct _stat *)stp);
      vim_free(wp);
      if (n >= 0)
      return n;
      --- 626,632 ----

      if (wp != NULL)
      {
      ! n = wstat_symlink_aware(wp, (struct _stat *)stp);
      vim_free(wp);
      if (n >= 0)
      return n;
      ***************
      *** 544,550 ****
      }
      }
      #endif
      ! return stat(buf, stp);
      }

      #if defined(FEAT_GUI_MSWIN) || defined(PROTO)
      --- 636,642 ----
      }
      }
      #endif
      ! return stat_symlink_aware(buf, stp);
      }

      #if defined(FEAT_GUI_MSWIN) || defined(PROTO)
      *** ../vim-7.4.038/src/os_win32.c 2013-08-30 17:29:10.000000000 +0200
      --- src/os_win32.c 2013-09-25 19:09:53.000000000 +0200
      ***************
      *** 78,93 ****
      # endif
      #endif

      - /*
      - * Reparse Point
      - */
      - #ifndef FILE_ATTRIBUTE_REPARSE_POINT
      - # define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
      - #endif
      - #ifndef IO_REPARSE_TAG_SYMLINK
      - # define IO_REPARSE_TAG_SYMLINK 0xA000000C
      - #endif
      -
      /* Record all output and all keyboard & mouse input */
      /* #define MCH_WRITE_DUMP */

      --- 78,83 ----
      *** ../vim-7.4.038/src/os_win32.h 2013-07-21 17:53:13.000000000 +0200
      --- src/os_win32.h 2013-09-25 19:09:53.000000000 +0200
      ***************
      *** 130,135 ****
      --- 130,148 ----
      # define DFLT_MAXMEMTOT (5*1024) /* use up to 5 Mbyte for Vim */
      #endif

      + /*
      + * Reparse Point
      + */
      + #ifndef FILE_ATTRIBUTE_REPARSE_POINT
      + # define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
      + #endif
      + #ifndef IO_REPARSE_TAG_MOUNT_POINT
      + # define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
      + #endif
      + #ifndef IO_REPARSE_TAG_SYMLINK
      + # define IO_REPARSE_TAG_SYMLINK 0xA000000C
      + #endif
      +
      #if defined(_MSC_VER) || defined(__BORLANDC__)
      /* Support for __try / __except. All versions of MSVC and Borland C are
      * expected to have this. Any other compilers that support it? */
      *** ../vim-7.4.038/src/version.c 2013-09-25 18:54:20.000000000 +0200
      --- src/version.c 2013-09-25 19:08:55.000000000 +0200
      ***************
      *** 740,741 ****
      --- 740,743 ----
      { /* Add new patch number below this line */
      + /**/
      + 39,
      /**/

      --
      A cow comes flying over the battlements, lowing aggressively. The cow
      lands on GALAHAD'S PAGE, squashing him completely.
      "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

      /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
      /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
      \\\ an exciting new programming language -- http://www.Zimbu.org ///
      \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

      --
      --
      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

      ---
      You received this message because you are subscribed to the Google Groups "vim_dev" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    Your message has been successfully submitted and would be delivered to recipients shortly.