Fossil SCM

Added code to detect if the working directory file system is one that supports symlinks so that we won't try to do symlink processing when the platform does not support it.

sdr 2014-09-24 06:06 winsymlink
Commit 5d251b673983cd93bd4eef26c87bd7608fed8752
2 files changed +1 -1 +33 -4
+1 -1
--- src/checkin.c
+++ src/checkin.c
@@ -1116,11 +1116,11 @@
11161116
mPerm = file_wd_perm(blob_str(&filename));
11171117
#if !defined(_WIN32)
11181118
isExe = ( mPerm==PERM_EXE );
11191119
#endif
11201120
#if defined(_WIN32)
1121
- if (win32_symlinks_supported())
1121
+ if (win32_symlinks_supported(blob_str(&filename)))
11221122
#endif
11231123
isLink = ( mPerm==PERM_LNK );
11241124
}
11251125
11261126
if( isExe ){
11271127
--- src/checkin.c
+++ src/checkin.c
@@ -1116,11 +1116,11 @@
1116 mPerm = file_wd_perm(blob_str(&filename));
1117 #if !defined(_WIN32)
1118 isExe = ( mPerm==PERM_EXE );
1119 #endif
1120 #if defined(_WIN32)
1121 if (win32_symlinks_supported())
1122 #endif
1123 isLink = ( mPerm==PERM_LNK );
1124 }
1125
1126 if( isExe ){
1127
--- src/checkin.c
+++ src/checkin.c
@@ -1116,11 +1116,11 @@
1116 mPerm = file_wd_perm(blob_str(&filename));
1117 #if !defined(_WIN32)
1118 isExe = ( mPerm==PERM_EXE );
1119 #endif
1120 #if defined(_WIN32)
1121 if (win32_symlinks_supported(blob_str(&filename)))
1122 #endif
1123 isLink = ( mPerm==PERM_LNK );
1124 }
1125
1126 if( isExe ){
1127
+33 -4
--- src/winfile.c
+++ src/winfile.c
@@ -276,22 +276,28 @@
276276
277277
return !created;
278278
}
279279
280280
/*
281
-** Check if symlinks are potentially supported on the current OS.
281
+** Check if symlinks are potentially supported on the current OS for the given file.
282282
** Theoretically this code should work on any NT based version of windows
283283
** but I have no way of testing that. The initial check for
284284
** IsWindowsVistaOrGreater() should in theory eliminate any system prior to
285285
** Windows Vista, but I have no way to test that at this time.
286286
** Return 1 if supported, 0 if not.
287287
*/
288
-int win32_symlinks_supported(){
288
+int win32_symlinks_supported(const char* zFilename){
289289
TOKEN_PRIVILEGES tp;
290290
LUID luid;
291291
HANDLE process, token;
292292
DWORD status;
293
+ int success;
294
+ wchar_t *pFilename;
295
+ wchar_t fullName[MAX_PATH+1];
296
+ DWORD fullLength;
297
+ wchar_t volName[MAX_PATH+1];
298
+ DWORD fsFlags;
293299
294300
/* symlinks only supported on vista or greater */
295301
if (!IsWindowsVistaOrGreater())
296302
return 0;
297303
@@ -319,13 +325,36 @@
319325
CloseHandle(token);
320326
321327
/* any error means we failed to enable the privilege, symlinks not supported */
322328
if (status != ERROR_SUCCESS)
323329
return 0;
330
+
331
+ /* assume no support for symlinks */
332
+ success = 0;
333
+
334
+ pFilename = fossil_utf8_to_filename(zFilename);
335
+
336
+ /* given the filename we're interested in, symlinks are supported if */
337
+ /* 1. we can get the full name of the path from the given path */
338
+ fullLength = GetFullPathNameW(pFilename, sizeof(fullName), fullName, NULL);
339
+ if ((fullLength > 0) && (fullLength < sizeof(fullName))){
340
+ /* 2. we can get the volume path name from the full name */
341
+ if (GetVolumePathNameW(fullName, volName, sizeof(volName))){
342
+ /* 3. we can get volume information from the volume path name */
343
+ if (GetVolumeInformationW(volName, NULL, 0, NULL, NULL, &fsFlags, NULL, 0)){
344
+ /* 4. the given volume support reparse points */
345
+ if (fsFlags & FILE_SUPPORTS_REPARSE_POINTS){
346
+ /* all four conditions were true, so we support symlinks; success! */
347
+ success = 1;
348
+ }
349
+ }
350
+ }
351
+ }
324352
325
- /* we made it this far, symlinks must be supported */
326
- return 1;
353
+ fossil_filename_free(pFilename);
354
+
355
+ return success;
327356
}
328357
329358
/*
330359
** Wrapper around the access() system call. This code was copied from Tcl
331360
** 8.6 and then modified.
332361
--- src/winfile.c
+++ src/winfile.c
@@ -276,22 +276,28 @@
276
277 return !created;
278 }
279
280 /*
281 ** Check if symlinks are potentially supported on the current OS.
282 ** Theoretically this code should work on any NT based version of windows
283 ** but I have no way of testing that. The initial check for
284 ** IsWindowsVistaOrGreater() should in theory eliminate any system prior to
285 ** Windows Vista, but I have no way to test that at this time.
286 ** Return 1 if supported, 0 if not.
287 */
288 int win32_symlinks_supported(){
289 TOKEN_PRIVILEGES tp;
290 LUID luid;
291 HANDLE process, token;
292 DWORD status;
 
 
 
 
 
 
293
294 /* symlinks only supported on vista or greater */
295 if (!IsWindowsVistaOrGreater())
296 return 0;
297
@@ -319,13 +325,36 @@
319 CloseHandle(token);
320
321 /* any error means we failed to enable the privilege, symlinks not supported */
322 if (status != ERROR_SUCCESS)
323 return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
325 /* we made it this far, symlinks must be supported */
326 return 1;
 
327 }
328
329 /*
330 ** Wrapper around the access() system call. This code was copied from Tcl
331 ** 8.6 and then modified.
332
--- src/winfile.c
+++ src/winfile.c
@@ -276,22 +276,28 @@
276
277 return !created;
278 }
279
280 /*
281 ** Check if symlinks are potentially supported on the current OS for the given file.
282 ** Theoretically this code should work on any NT based version of windows
283 ** but I have no way of testing that. The initial check for
284 ** IsWindowsVistaOrGreater() should in theory eliminate any system prior to
285 ** Windows Vista, but I have no way to test that at this time.
286 ** Return 1 if supported, 0 if not.
287 */
288 int win32_symlinks_supported(const char* zFilename){
289 TOKEN_PRIVILEGES tp;
290 LUID luid;
291 HANDLE process, token;
292 DWORD status;
293 int success;
294 wchar_t *pFilename;
295 wchar_t fullName[MAX_PATH+1];
296 DWORD fullLength;
297 wchar_t volName[MAX_PATH+1];
298 DWORD fsFlags;
299
300 /* symlinks only supported on vista or greater */
301 if (!IsWindowsVistaOrGreater())
302 return 0;
303
@@ -319,13 +325,36 @@
325 CloseHandle(token);
326
327 /* any error means we failed to enable the privilege, symlinks not supported */
328 if (status != ERROR_SUCCESS)
329 return 0;
330
331 /* assume no support for symlinks */
332 success = 0;
333
334 pFilename = fossil_utf8_to_filename(zFilename);
335
336 /* given the filename we're interested in, symlinks are supported if */
337 /* 1. we can get the full name of the path from the given path */
338 fullLength = GetFullPathNameW(pFilename, sizeof(fullName), fullName, NULL);
339 if ((fullLength > 0) && (fullLength < sizeof(fullName))){
340 /* 2. we can get the volume path name from the full name */
341 if (GetVolumePathNameW(fullName, volName, sizeof(volName))){
342 /* 3. we can get volume information from the volume path name */
343 if (GetVolumeInformationW(volName, NULL, 0, NULL, NULL, &fsFlags, NULL, 0)){
344 /* 4. the given volume support reparse points */
345 if (fsFlags & FILE_SUPPORTS_REPARSE_POINTS){
346 /* all four conditions were true, so we support symlinks; success! */
347 success = 1;
348 }
349 }
350 }
351 }
352
353 fossil_filename_free(pFilename);
354
355 return success;
356 }
357
358 /*
359 ** Wrapper around the access() system call. This code was copied from Tcl
360 ** 8.6 and then modified.
361

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button