home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.3 / 7.3.1182 < prev    next >
Encoding:
Internet Message Format  |  2013-06-11  |  13.2 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.1182
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.3.1182
  11. Problem:    'backupcopy' default on MS-Windows does not work for hard and soft
  12.         links.
  13. Solution:   Check for links. (David Pope, Ken Takata)
  14. Files:        src/fileio.c, src/os_win32.c, src/proto/os_win32.pro
  15.  
  16.  
  17. *** ../vim-7.3.1181/src/fileio.c    2013-06-12 19:52:11.000000000 +0200
  18. --- src/fileio.c    2013-06-12 22:31:34.000000000 +0200
  19. ***************
  20. *** 3780,3791 ****
  21.           }
  22.       }
  23.   
  24. - # ifdef UNIX
  25.       /*
  26.        * Break symlinks and/or hardlinks if we've been asked to.
  27.        */
  28.       if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK))
  29.       {
  30.           int    lstat_res;
  31.   
  32.           lstat_res = mch_lstat((char *)fname, &st);
  33. --- 3780,3791 ----
  34.           }
  35.       }
  36.   
  37.       /*
  38.        * Break symlinks and/or hardlinks if we've been asked to.
  39.        */
  40.       if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK))
  41.       {
  42. + # ifdef UNIX
  43.           int    lstat_res;
  44.   
  45.           lstat_res = mch_lstat((char *)fname, &st);
  46. ***************
  47. *** 3801,3808 ****
  48.               && st_old.st_nlink > 1
  49.               && (lstat_res != 0 || st.st_ino == st_old.st_ino))
  50.           backup_copy = FALSE;
  51.       }
  52. - #endif
  53.   
  54.   #endif
  55.   
  56. --- 3801,3818 ----
  57.               && st_old.st_nlink > 1
  58.               && (lstat_res != 0 || st.st_ino == st_old.st_ino))
  59.           backup_copy = FALSE;
  60. + # else
  61. + #  if defined(WIN32)
  62. +         /* Symlinks. */
  63. +         if ((bkc_flags & BKC_BREAKSYMLINK) && mch_is_symbolic_link(fname))
  64. +         backup_copy = FALSE;
  65. +         /* Hardlinks. */
  66. +         if ((bkc_flags & BKC_BREAKHARDLINK) && mch_is_hard_link(fname))
  67. +         backup_copy = FALSE;
  68. + #  endif
  69. + # endif
  70.       }
  71.   
  72.   #endif
  73.   
  74. *** ../vim-7.3.1181/src/os_win32.c    2013-06-07 19:17:12.000000000 +0200
  75. --- src/os_win32.c    2013-06-12 22:39:53.000000000 +0200
  76. ***************
  77. *** 78,83 ****
  78. --- 78,93 ----
  79.   # endif
  80.   #endif
  81.   
  82. + /*
  83. +  * Reparse Point
  84. +  */
  85. + #ifndef FILE_ATTRIBUTE_REPARSE_POINT
  86. + # define FILE_ATTRIBUTE_REPARSE_POINT    0x00000400
  87. + #endif
  88. + #ifndef IO_REPARSE_TAG_SYMLINK
  89. + # define IO_REPARSE_TAG_SYMLINK        0xA000000C
  90. + #endif
  91.   /* Record all output and all keyboard & mouse input */
  92.   /* #define MCH_WRITE_DUMP */
  93.   
  94. ***************
  95. *** 219,224 ****
  96. --- 229,238 ----
  97.   static char *vimrun_path = "vimrun ";
  98.   #endif
  99.   
  100. + static int win32_getattrs(char_u *name);
  101. + static int win32_setattrs(char_u *name, int attrs);
  102. + static int win32_set_archive(char_u *name);
  103.   #ifndef FEAT_GUI_W32
  104.   static int suppress_winsize = 1;    /* don't fiddle with console */
  105.   #endif
  106. ***************
  107. *** 2623,2679 ****
  108.   /*
  109.    * get file permissions for `name'
  110.    * -1 : error
  111. !  * else FILE_ATTRIBUTE_* defined in winnt.h
  112.    */
  113.       long
  114.   mch_getperm(char_u *name)
  115.   {
  116. ! #ifdef FEAT_MBYTE
  117. !     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  118. !     {
  119. !     WCHAR    *p = enc_to_utf16(name, NULL);
  120. !     long    n;
  121.   
  122. !     if (p != NULL)
  123. !     {
  124. !         n = (long)GetFileAttributesW(p);
  125. !         vim_free(p);
  126. !         if (n >= 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
  127. !         return n;
  128. !         /* Retry with non-wide function (for Windows 98). */
  129. !     }
  130. !     }
  131. ! #endif
  132. !     return (long)GetFileAttributes((char *)name);
  133.   }
  134.   
  135.   
  136.   /*
  137.    * set file permission for `name' to `perm'
  138.    */
  139.       int
  140.   mch_setperm(
  141.       char_u  *name,
  142.       long    perm)
  143.   {
  144. !     perm |= FILE_ATTRIBUTE_ARCHIVE;    /* file has changed, set archive bit */
  145.   #ifdef FEAT_MBYTE
  146.       if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  147.       {
  148. !     WCHAR    *p = enc_to_utf16(name, NULL);
  149. !     long    n;
  150.   
  151.       if (p != NULL)
  152.       {
  153. !         n = (long)SetFileAttributesW(p, perm);
  154.           vim_free(p);
  155. !         if (n || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
  156. !         return n ? OK : FAIL;
  157.           /* Retry with non-wide function (for Windows 98). */
  158.       }
  159.       }
  160.   #endif
  161. !     return SetFileAttributes((char *)name, perm) ? OK : FAIL;
  162.   }
  163.   
  164.   /*
  165. --- 2637,2690 ----
  166.   /*
  167.    * get file permissions for `name'
  168.    * -1 : error
  169. !  * else mode_t
  170.    */
  171.       long
  172.   mch_getperm(char_u *name)
  173.   {
  174. !     struct stat st;
  175. !     int n;
  176.   
  177. !     n = mch_stat(name, &st);
  178. !     return n == 0 ? (int)st.st_mode : -1;
  179.   }
  180.   
  181.   
  182.   /*
  183.    * set file permission for `name' to `perm'
  184. +  *
  185. +  * return FAIL for failure, OK otherwise
  186.    */
  187.       int
  188.   mch_setperm(
  189.       char_u  *name,
  190.       long    perm)
  191.   {
  192. !     long    n;
  193.   #ifdef FEAT_MBYTE
  194. +     WCHAR *p;
  195.       if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  196.       {
  197. !     p = enc_to_utf16(name, NULL);
  198.   
  199.       if (p != NULL)
  200.       {
  201. !         n = _wchmod(p, perm);
  202.           vim_free(p);
  203. !         if (n == -1 && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
  204. !         return FAIL;
  205.           /* Retry with non-wide function (for Windows 98). */
  206.       }
  207.       }
  208. +     if (p == NULL)
  209.   #endif
  210. !     n = _chmod(name, perm);
  211. !     if (n == -1)
  212. !     return FAIL;
  213. !     win32_set_archive(name);
  214. !     return OK;
  215.   }
  216.   
  217.   /*
  218. ***************
  219. *** 2682,2730 ****
  220.       void
  221.   mch_hide(char_u *name)
  222.   {
  223. !     int        perm;
  224. ! #ifdef FEAT_MBYTE
  225. !     WCHAR    *p = NULL;
  226. !     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  227. !     p = enc_to_utf16(name, NULL);
  228. ! #endif
  229.   
  230. ! #ifdef FEAT_MBYTE
  231. !     if (p != NULL)
  232. !     {
  233. !     perm = GetFileAttributesW(p);
  234. !     if (perm < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  235. !     {
  236. !         /* Retry with non-wide function (for Windows 98). */
  237. !         vim_free(p);
  238. !         p = NULL;
  239. !     }
  240. !     }
  241. !     if (p == NULL)
  242. ! #endif
  243. !     perm = GetFileAttributes((char *)name);
  244. !     if (perm >= 0)
  245. !     {
  246. !     perm |= FILE_ATTRIBUTE_HIDDEN;
  247. ! #ifdef FEAT_MBYTE
  248. !     if (p != NULL)
  249. !     {
  250. !         if (SetFileAttributesW(p, perm) == 0
  251. !             && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  252. !         {
  253. !         /* Retry with non-wide function (for Windows 98). */
  254. !         vim_free(p);
  255. !         p = NULL;
  256. !         }
  257. !     }
  258. !     if (p == NULL)
  259. ! #endif
  260. !         SetFileAttributes((char *)name, perm);
  261. !     }
  262. ! #ifdef FEAT_MBYTE
  263. !     vim_free(p);
  264. ! #endif
  265.   }
  266.   
  267.   /*
  268. --- 2693,2704 ----
  269.       void
  270.   mch_hide(char_u *name)
  271.   {
  272. !     int attrs = win32_getattrs(name);
  273. !     if (attrs == -1)
  274. !     return;
  275.   
  276. !     attrs |= FILE_ATTRIBUTE_HIDDEN;
  277. !     win32_setattrs(name, attrs);
  278.   }
  279.   
  280.   /*
  281. ***************
  282. *** 2734,2740 ****
  283.       int
  284.   mch_isdir(char_u *name)
  285.   {
  286. !     int f = mch_getperm(name);
  287.   
  288.       if (f == -1)
  289.       return FALSE;            /* file does not exist at all */
  290. --- 2708,2714 ----
  291.       int
  292.   mch_isdir(char_u *name)
  293.   {
  294. !     int f = win32_getattrs(name);
  295.   
  296.       if (f == -1)
  297.       return FALSE;            /* file does not exist at all */
  298. ***************
  299. *** 2770,2776 ****
  300.    * Return TRUE if file "fname" has more than one link.
  301.    */
  302.       int
  303. ! mch_is_linked(char_u *fname)
  304.   {
  305.       BY_HANDLE_FILE_INFORMATION info;
  306.   
  307. --- 2744,2750 ----
  308.    * Return TRUE if file "fname" has more than one link.
  309.    */
  310.       int
  311. ! mch_is_hard_link(char_u *fname)
  312.   {
  313.       BY_HANDLE_FILE_INFORMATION info;
  314.   
  315. ***************
  316. *** 2779,2784 ****
  317. --- 2753,2826 ----
  318.   }
  319.   
  320.   /*
  321. +  * Return TRUE if file "fname" is a symbolic link.
  322. +  */
  323. +     int
  324. + mch_is_symbolic_link(char_u *fname)
  325. + {
  326. +     HANDLE        hFind;
  327. +     int            res = FALSE;
  328. +     WIN32_FIND_DATAA    findDataA;
  329. +     DWORD        fileFlags = 0, reparseTag = 0;
  330. + #ifdef FEAT_MBYTE
  331. +     WCHAR        *wn = NULL;
  332. +     WIN32_FIND_DATAW    findDataW;
  333. +     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  334. +     wn = enc_to_utf16(fname, NULL);
  335. +     if (wn != NULL)
  336. +     {
  337. +     hFind = FindFirstFileW(wn, &findDataW);
  338. +     vim_free(wn);
  339. +     if (hFind == INVALID_HANDLE_VALUE
  340. +         && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  341. +     {
  342. +         /* Retry with non-wide function (for Windows 98). */
  343. +         hFind = FindFirstFile(fname, &findDataA);
  344. +         if (hFind != INVALID_HANDLE_VALUE)
  345. +         {
  346. +         fileFlags = findDataA.dwFileAttributes;
  347. +         reparseTag = findDataA.dwReserved0;
  348. +         }
  349. +     }
  350. +     else
  351. +     {
  352. +         fileFlags = findDataW.dwFileAttributes;
  353. +         reparseTag = findDataW.dwReserved0;
  354. +     }
  355. +     }
  356. + #else
  357. +     hFind = FindFirstFile(fname, &findDataA);
  358. +     if (hFind != INVALID_HANDLE_VALUE)
  359. +     {
  360. +     fileFlags = findDataA.dwFileAttributes;
  361. +     reparseTag = findDataA.dwReserved0;
  362. +     }
  363. + #endif
  364. +     if (hFind != INVALID_HANDLE_VALUE)
  365. +     FindClose(hFind);
  366. +     if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT)
  367. +         && reparseTag == IO_REPARSE_TAG_SYMLINK)
  368. +     res = TRUE;
  369. +     return res;
  370. + }
  371. + /*
  372. +  * Return TRUE if file "fname" has more than one link or if it is a symbolic
  373. +  * link.
  374. +  */
  375. +     int
  376. + mch_is_linked(char_u *fname)
  377. + {
  378. +     if (mch_is_hard_link(fname) || mch_is_symbolic_link(fname))
  379. +     return TRUE;
  380. +     return FALSE;
  381. + }
  382. + /*
  383.    * Get the by-handle-file-information for "fname".
  384.    * Returns FILEINFO_OK when OK.
  385.    * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed.
  386. ***************
  387. *** 2842,2847 ****
  388. --- 2884,2975 ----
  389.   }
  390.   
  391.   /*
  392. +  * get file attributes for `name'
  393. +  * -1 : error
  394. +  * else FILE_ATTRIBUTE_* defined in winnt.h
  395. +  */
  396. +     static
  397. +     int
  398. + win32_getattrs(char_u *name)
  399. + {
  400. +     int        attr;
  401. + #ifdef FEAT_MBYTE
  402. +     WCHAR    *p = NULL;
  403. +     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  404. +     p = enc_to_utf16(name, NULL);
  405. +     if (p != NULL)
  406. +     {
  407. +     attr = GetFileAttributesW(p);
  408. +     if (attr < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  409. +     {
  410. +         /* Retry with non-wide function (for Windows 98). */
  411. +         vim_free(p);
  412. +         p = NULL;
  413. +     }
  414. +     }
  415. +     if (p == NULL)
  416. + #endif
  417. +     attr = GetFileAttributes((char *)name);
  418. + #ifdef FEAT_MBYTE
  419. +     vim_free(p);
  420. + #endif
  421. +     return attr;
  422. + }
  423. + /*
  424. +  * set file attributes for `name' to `attrs'
  425. +  *
  426. +  * return -1 for failure, 0 otherwise
  427. +  */
  428. +     static
  429. +     int
  430. + win32_setattrs(char_u *name, int attrs)
  431. + {
  432. +     int res;
  433. + #ifdef FEAT_MBYTE
  434. +     WCHAR    *p = NULL;
  435. +     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  436. +     p = enc_to_utf16(name, NULL);
  437. +     if (p != NULL)
  438. +     {
  439. +     res = SetFileAttributesW(p, attrs);
  440. +     if (res == FALSE
  441. +         && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  442. +     {
  443. +         /* Retry with non-wide function (for Windows 98). */
  444. +         vim_free(p);
  445. +         p = NULL;
  446. +     }
  447. +     }
  448. +     if (p == NULL)
  449. + #endif
  450. +     res = SetFileAttributes((char *)name, attrs);
  451. + #ifdef FEAT_MBYTE
  452. +     vim_free(p);
  453. + #endif
  454. +     return res ? 0 : -1;
  455. + }
  456. + /*
  457. +  * Set archive flag for "name".
  458. +  */
  459. +     static
  460. +     int
  461. + win32_set_archive(char_u *name)
  462. + {
  463. +     int attrs = win32_getattrs(name);
  464. +     if (attrs == -1)
  465. +     return -1;
  466. +     attrs |= FILE_ATTRIBUTE_ARCHIVE;
  467. +     return win32_setattrs(name, attrs);
  468. + }
  469. + /*
  470.    * Return TRUE if file or directory "name" is writable (not readonly).
  471.    * Strange semantics of Win32: a readonly directory is writable, but you can't
  472.    * delete a file.  Let's say this means it is writable.
  473. ***************
  474. *** 2849,2858 ****
  475.       int
  476.   mch_writable(char_u *name)
  477.   {
  478. !     int perm = mch_getperm(name);
  479.   
  480. !     return (perm != -1 && (!(perm & FILE_ATTRIBUTE_READONLY)
  481. !                        || (perm & FILE_ATTRIBUTE_DIRECTORY)));
  482.   }
  483.   
  484.   /*
  485. --- 2977,2986 ----
  486.       int
  487.   mch_writable(char_u *name)
  488.   {
  489. !     int attrs = win32_getattrs(name);
  490.   
  491. !     return (attrs != -1 && (!(attrs & FILE_ATTRIBUTE_READONLY)
  492. !               || (attrs & FILE_ATTRIBUTE_DIRECTORY)));
  493.   }
  494.   
  495.   /*
  496. ***************
  497. *** 5012,5024 ****
  498.   #ifdef FEAT_MBYTE
  499.       WCHAR    *wn = NULL;
  500.       int        n;
  501.   
  502.       if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  503.       {
  504.       wn = enc_to_utf16(name, NULL);
  505.       if (wn != NULL)
  506.       {
  507. -         SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL);
  508.           n = DeleteFileW(wn) ? 0 : -1;
  509.           vim_free(wn);
  510.           if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
  511. --- 5140,5155 ----
  512.   #ifdef FEAT_MBYTE
  513.       WCHAR    *wn = NULL;
  514.       int        n;
  515. + #endif
  516.   
  517. +     win32_setattrs(name, FILE_ATTRIBUTE_NORMAL);
  518. + #ifdef FEAT_MBYTE
  519.       if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  520.       {
  521.       wn = enc_to_utf16(name, NULL);
  522.       if (wn != NULL)
  523.       {
  524.           n = DeleteFileW(wn) ? 0 : -1;
  525.           vim_free(wn);
  526.           if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
  527. ***************
  528. *** 5027,5033 ****
  529.       }
  530.       }
  531.   #endif
  532. -     SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL);
  533.       return DeleteFile(name) ? 0 : -1;
  534.   }
  535.   
  536. --- 5158,5163 ----
  537. *** ../vim-7.3.1181/src/proto/os_win32.pro    2012-11-20 16:56:49.000000000 +0100
  538. --- src/proto/os_win32.pro    2013-06-12 22:29:53.000000000 +0200
  539. ***************
  540. *** 21,26 ****
  541. --- 21,28 ----
  542.   void mch_hide __ARGS((char_u *name));
  543.   int mch_isdir __ARGS((char_u *name));
  544.   int mch_mkdir __ARGS((char_u *name));
  545. + int mch_is_hard_link __ARGS((char_u *fname));
  546. + int mch_is_symbolic_link __ARGS((char_u *fname));
  547.   int mch_is_linked __ARGS((char_u *fname));
  548.   int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info));
  549.   int mch_writable __ARGS((char_u *name));
  550. *** ../vim-7.3.1181/src/version.c    2013-06-12 22:08:54.000000000 +0200
  551. --- src/version.c    2013-06-12 22:40:29.000000000 +0200
  552. ***************
  553. *** 730,731 ****
  554. --- 730,733 ----
  555.   {   /* Add new patch number below this line */
  556. + /**/
  557. +     1182,
  558.   /**/
  559.  
  560. -- 
  561. If Microsoft would build a car...
  562. ... You'd have to press the "Start" button to turn the engine off.
  563.  
  564.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  565. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  566. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  567.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  568.