Fossil SCM
Fixed a problem with the high level symlink creation code to accommodate windows drive letters. Also modified windows symlink creation logic to better handle dir/file symlinks.
Commit
1f1f75066a2e4a3dd24d97d4f5e3493dd751fde1
Parent
e2c5960617f2c9d…
2 files changed
+11
+13
-3
+11
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -207,14 +207,25 @@ | ||
| 207 | 207 | } |
| 208 | 208 | nName = file_simplify_name(zName, nName, 0); |
| 209 | 209 | for(i=1; i<nName; i++){ |
| 210 | 210 | if( zName[i]=='/' ){ |
| 211 | 211 | zName[i] = 0; |
| 212 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
| 213 | + /* | |
| 214 | + ** On Windows, local path looks like: C:/develop/project/file.txt | |
| 215 | + ** The if stops us from trying to create a directory of a drive letter | |
| 216 | + ** C: in this example. | |
| 217 | + */ | |
| 218 | + if (!(i == 2 && zName[1] == ':')){ | |
| 219 | +#endif | |
| 212 | 220 | if( file_mkdir(zName, 1) ){ |
| 213 | 221 | fossil_fatal_recursive("unable to create directory %s", zName); |
| 214 | 222 | return; |
| 215 | 223 | } |
| 224 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
| 225 | + } | |
| 226 | +#endif | |
| 216 | 227 | zName[i] = '/'; |
| 217 | 228 | } |
| 218 | 229 | } |
| 219 | 230 | #if !defined(_WIN32) |
| 220 | 231 | if( symlink(zTargetFile, zName)!=0 ) |
| 221 | 232 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -207,14 +207,25 @@ | |
| 207 | } |
| 208 | nName = file_simplify_name(zName, nName, 0); |
| 209 | for(i=1; i<nName; i++){ |
| 210 | if( zName[i]=='/' ){ |
| 211 | zName[i] = 0; |
| 212 | if( file_mkdir(zName, 1) ){ |
| 213 | fossil_fatal_recursive("unable to create directory %s", zName); |
| 214 | return; |
| 215 | } |
| 216 | zName[i] = '/'; |
| 217 | } |
| 218 | } |
| 219 | #if !defined(_WIN32) |
| 220 | if( symlink(zTargetFile, zName)!=0 ) |
| 221 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -207,14 +207,25 @@ | |
| 207 | } |
| 208 | nName = file_simplify_name(zName, nName, 0); |
| 209 | for(i=1; i<nName; i++){ |
| 210 | if( zName[i]=='/' ){ |
| 211 | zName[i] = 0; |
| 212 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 213 | /* |
| 214 | ** On Windows, local path looks like: C:/develop/project/file.txt |
| 215 | ** The if stops us from trying to create a directory of a drive letter |
| 216 | ** C: in this example. |
| 217 | */ |
| 218 | if (!(i == 2 && zName[1] == ':')){ |
| 219 | #endif |
| 220 | if( file_mkdir(zName, 1) ){ |
| 221 | fossil_fatal_recursive("unable to create directory %s", zName); |
| 222 | return; |
| 223 | } |
| 224 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 225 | } |
| 226 | #endif |
| 227 | zName[i] = '/'; |
| 228 | } |
| 229 | } |
| 230 | #if !defined(_WIN32) |
| 231 | if( symlink(zTargetFile, zName)!=0 ) |
| 232 |
+13
-3
| --- src/winfile.c | ||
| +++ src/winfile.c | ||
| @@ -187,15 +187,25 @@ | ||
| 187 | 187 | /* does oldpath exist? is it a dir or a file? */ |
| 188 | 188 | zMbcs = fossil_utf8_to_filename(oldpath); |
| 189 | 189 | if (win32_stat(zMbcs, &stat) == 0){ |
| 190 | 190 | if (stat.st_mode == S_IFDIR) |
| 191 | 191 | flags = SYMBOLIC_LINK_FLAG_DIRECTORY; |
| 192 | - DeleteFile(newpath); | |
| 193 | - if (CreateSymbolicLink(newpath, oldpath, flags)) | |
| 194 | - created = 1; | |
| 192 | + } | |
| 193 | + fossil_filename_free(zMbcs); | |
| 194 | + | |
| 195 | + /* remove newpath before creating the symlink */ | |
| 196 | + zMbcs = fossil_utf8_to_filename(newpath); | |
| 197 | + if (win32_stat(zMbcs, &stat) == 0){ | |
| 198 | + if (stat.st_mode == S_IFDIR) | |
| 199 | + RemoveDirectory(newpath); | |
| 200 | + else | |
| 201 | + DeleteFile(newpath); | |
| 195 | 202 | } |
| 196 | 203 | fossil_filename_free(zMbcs); |
| 204 | + | |
| 205 | + if (CreateSymbolicLink(newpath, oldpath, flags)) | |
| 206 | + created = 1; | |
| 197 | 207 | |
| 198 | 208 | /* if the symlink was not created, create a plain text file */ |
| 199 | 209 | if (!created){ |
| 200 | 210 | Blob content; |
| 201 | 211 | blob_set(&content, oldpath); |
| 202 | 212 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -187,15 +187,25 @@ | |
| 187 | /* does oldpath exist? is it a dir or a file? */ |
| 188 | zMbcs = fossil_utf8_to_filename(oldpath); |
| 189 | if (win32_stat(zMbcs, &stat) == 0){ |
| 190 | if (stat.st_mode == S_IFDIR) |
| 191 | flags = SYMBOLIC_LINK_FLAG_DIRECTORY; |
| 192 | DeleteFile(newpath); |
| 193 | if (CreateSymbolicLink(newpath, oldpath, flags)) |
| 194 | created = 1; |
| 195 | } |
| 196 | fossil_filename_free(zMbcs); |
| 197 | |
| 198 | /* if the symlink was not created, create a plain text file */ |
| 199 | if (!created){ |
| 200 | Blob content; |
| 201 | blob_set(&content, oldpath); |
| 202 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -187,15 +187,25 @@ | |
| 187 | /* does oldpath exist? is it a dir or a file? */ |
| 188 | zMbcs = fossil_utf8_to_filename(oldpath); |
| 189 | if (win32_stat(zMbcs, &stat) == 0){ |
| 190 | if (stat.st_mode == S_IFDIR) |
| 191 | flags = SYMBOLIC_LINK_FLAG_DIRECTORY; |
| 192 | } |
| 193 | fossil_filename_free(zMbcs); |
| 194 | |
| 195 | /* remove newpath before creating the symlink */ |
| 196 | zMbcs = fossil_utf8_to_filename(newpath); |
| 197 | if (win32_stat(zMbcs, &stat) == 0){ |
| 198 | if (stat.st_mode == S_IFDIR) |
| 199 | RemoveDirectory(newpath); |
| 200 | else |
| 201 | DeleteFile(newpath); |
| 202 | } |
| 203 | fossil_filename_free(zMbcs); |
| 204 | |
| 205 | if (CreateSymbolicLink(newpath, oldpath, flags)) |
| 206 | created = 1; |
| 207 | |
| 208 | /* if the symlink was not created, create a plain text file */ |
| 209 | if (!created){ |
| 210 | Blob content; |
| 211 | blob_set(&content, oldpath); |
| 212 |