diff options
| author | LynX | 2012-01-07 11:50:57 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-01-07 11:50:57 +0200 |
| commit | 069d2b507080e2cb2b4f9ed112c9b7d8c3f2dc22 (patch) | |
| tree | ccd1ba62708aec369c08772c2d92c65eec4717ca /src | |
| parent | e490b28922e17178224c6842b40429675b751cc8 (diff) | |
| download | emacs-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/ChangeLog | 5 | ||||
| -rw-r--r-- | src/w32.c | 40 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-01-07 David Benjamin <davidben@mit.edu> (tiny change) | 6 | 2012-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. |
| @@ -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 | } |