aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLynX2012-01-07 11:50:57 +0200
committerEli Zaretskii2012-01-07 11:50:57 +0200
commit069d2b507080e2cb2b4f9ed112c9b7d8c3f2dc22 (patch)
treeccd1ba62708aec369c08772c2d92c65eec4717ca /src
parente490b28922e17178224c6842b40429675b751cc8 (diff)
downloademacs-069d2b507080e2cb2b4f9ed112c9b7d8c3f2dc22.tar.gz
emacs-069d2b507080e2cb2b4f9ed112c9b7d8c3f2dc22.zip
Fix bug #10284 with renaming a directory on MS-Windows.
src/w32.c (sys_rename): Report EXDEV when rename of a directory fails because the target is on another logical disk. (Bug#10284)
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/w32.c40
2 files changed, 40 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 468e73c190b..3e0eed38cfb 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12012-01-07 LynX <_LynX@bk.ru> (tiny change)
2
3 * w32.c (sys_rename): Report EXDEV when rename of a directory
4 fails because the target is on another logical disk. (Bug#10284)
5
12012-01-07 David Benjamin <davidben@mit.edu> (tiny change) 62012-01-07 David Benjamin <davidben@mit.edu> (tiny change)
2 7
3 * xterm.c (x_embed_request_focus): New function. 8 * xterm.c (x_embed_request_focus): New function.
diff --git a/src/w32.c b/src/w32.c
index 3c277668949..f610a36ecf4 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -2894,6 +2894,8 @@ sys_rename (const char * oldname, const char * newname)
2894{ 2894{
2895 BOOL result; 2895 BOOL result;
2896 char temp[MAX_PATH]; 2896 char temp[MAX_PATH];
2897 int newname_dev;
2898 int oldname_dev;
2897 2899
2898 /* MoveFile on Windows 95 doesn't correctly change the short file name 2900 /* MoveFile on Windows 95 doesn't correctly change the short file name
2899 alias in a number of circumstances (it is not easy to predict when 2901 alias in a number of circumstances (it is not easy to predict when
@@ -2910,6 +2912,9 @@ sys_rename (const char * oldname, const char * newname)
2910 2912
2911 strcpy (temp, map_w32_filename (oldname, NULL)); 2913 strcpy (temp, map_w32_filename (oldname, NULL));
2912 2914
2915 /* volume_info is set indirectly by map_w32_filename. */
2916 oldname_dev = volume_info.serialnum;
2917
2913 if (os_subtype == OS_WIN95) 2918 if (os_subtype == OS_WIN95)
2914 { 2919 {
2915 char * o; 2920 char * o;
@@ -2953,13 +2958,38 @@ sys_rename (const char * oldname, const char * newname)
2953 all the permutations of shared or subst'd drives, etc.) */ 2958 all the permutations of shared or subst'd drives, etc.) */
2954 2959
2955 newname = map_w32_filename (newname, NULL); 2960 newname = map_w32_filename (newname, NULL);
2961
2962 /* volume_info is set indirectly by map_w32_filename. */
2963 newname_dev = volume_info.serialnum;
2964
2956 result = rename (temp, newname); 2965 result = rename (temp, newname);
2957 2966
2958 if (result < 0 2967 if (result < 0)
2959 && errno == EEXIST 2968 {
2960 && _chmod (newname, 0666) == 0 2969
2961 && _unlink (newname) == 0) 2970 if (errno == EACCES
2962 result = rename (temp, newname); 2971 && newname_dev != oldname_dev)
2972 {
2973 /* The implementation of `rename' on Windows does not return
2974 errno = EXDEV when you are moving a directory to a
2975 different storage device (ex. logical disk). It returns
2976 EACCES instead. So here we handle such situations and
2977 return EXDEV. */
2978 DWORD attributes;
2979
2980 if ((attributes = GetFileAttributes (temp)) != -1
2981 && attributes & FILE_ATTRIBUTE_DIRECTORY)
2982 errno = EXDEV;
2983 }
2984 else if (errno == EEXIST)
2985 {
2986 if (_chmod (newname, 0666) != 0)
2987 return result;
2988 if (_unlink (newname) != 0)
2989 return result;
2990 result = rename (temp, newname);
2991 }
2992 }
2963 2993
2964 return result; 2994 return result;
2965} 2995}