Fossil SCM

Fix fossil_stat() and fossil_chdir() such that they accept paths>MAX_PATH. For file_access(), implement a workaround that the '\\?\' prefix can be handled.

jan.nijtmans 2013-12-12 13:54 win32-longpath
Commit 29f023fe536c49b2bfc222e785b3e5ec6ea1aac5
1 file changed +29 -13
+29 -13
--- src/file.c
+++ src/file.c
@@ -47,11 +47,16 @@
4747
** Use _stati64 rather than stat on windows, in order to handle files
4848
** larger than 2GB.
4949
*/
5050
#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
5151
# undef stat
52
-# define stat _stati64
52
+# define stat _fossil_stati64
53
+struct stat {
54
+ i64 st_size;
55
+ i64 st_mtime;
56
+ int st_mode;
57
+};
5358
#endif
5459
/*
5560
** On Windows S_ISLNK always returns FALSE.
5661
*/
5762
#if !defined(S_ISLNK)
@@ -73,21 +78,21 @@
7378
rc = lstat(zMbcs, buf);
7479
}else{
7580
rc = stat(zMbcs, buf);
7681
}
7782
#else
83
+ WIN32_FILE_ATTRIBUTE_DATA attr;
7884
wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
79
- if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
80
- /* Unfortunately, _wstati64 cannot handle extended prefixes. */
81
- if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
82
- zMbcs[6] = '\\';
83
- rc = _wstati64(zMbcs+6, buf);
84
- }else{
85
- rc = _wstati64(zMbcs+4, buf);
86
- }
87
- }else{
88
- rc = _wstati64(zMbcs, buf);
85
+ rc = !GetFileAttributesExW(zMbcs, GetFileExInfoStandard, &attr);
86
+ if( !rc ){
87
+ ULARGE_INTEGER ull;
88
+ ull.LowPart = attr.ftLastWriteTime.dwLowDateTime;
89
+ ull.HighPart = attr.ftLastWriteTime.dwHighDateTime;
90
+ buf->st_mode = (attr.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)?
91
+ S_IFDIR:S_IFREG;
92
+ buf->st_size = (((i64)attr.nFileSizeHigh)<<32) | buf->attr.nFileSizeLow;
93
+ buf->st_mtime = ull.QuadPart / 10000000ULL - 11644473600ULL;
8994
}
9095
#endif
9196
fossil_filename_free(zMbcs);
9297
return rc;
9398
}
@@ -314,11 +319,22 @@
314319
** Wrapper around the access() system call.
315320
*/
316321
int file_access(const char *zFilename, int flags){
317322
#ifdef _WIN32
318323
wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
319
- int rc = _waccess(zMbcs, flags);
324
+ int rc;
325
+ if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
326
+ /* Unfortunately, _waccess cannot handle extended prefixes. */
327
+ if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
328
+ zMbcs[6] = '\\';
329
+ rc = _waccess(zMbcs+6, flags);
330
+ }else{
331
+ rc = _waccess(zMbcs+4, flags);
332
+ }
333
+ }else{
334
+ rc = _waccess(zMbcs, flags);
335
+ }
320336
#else
321337
char *zMbcs = fossil_utf8_to_filename(zFilename);
322338
int rc = access(zMbcs, flags);
323339
#endif
324340
fossil_filename_free(zMbcs);
@@ -331,11 +347,11 @@
331347
** (UNIX only)
332348
*/
333349
int file_chdir(const char *zChDir, int bChroot){
334350
#ifdef _WIN32
335351
wchar_t *zPath = fossil_utf8_to_filename(zChDir);
336
- int rc = _wchdir(zPath);
352
+ int rc = SetCurrentDirectoryW(zPath)==0;
337353
#else
338354
char *zPath = fossil_utf8_to_filename(zChDir);
339355
int rc = chdir(zPath);
340356
if( !rc && bChroot ){
341357
rc = chroot(zPath);
342358
--- src/file.c
+++ src/file.c
@@ -47,11 +47,16 @@
47 ** Use _stati64 rather than stat on windows, in order to handle files
48 ** larger than 2GB.
49 */
50 #if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
51 # undef stat
52 # define stat _stati64
 
 
 
 
 
53 #endif
54 /*
55 ** On Windows S_ISLNK always returns FALSE.
56 */
57 #if !defined(S_ISLNK)
@@ -73,21 +78,21 @@
73 rc = lstat(zMbcs, buf);
74 }else{
75 rc = stat(zMbcs, buf);
76 }
77 #else
 
78 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
79 if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
80 /* Unfortunately, _wstati64 cannot handle extended prefixes. */
81 if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
82 zMbcs[6] = '\\';
83 rc = _wstati64(zMbcs+6, buf);
84 }else{
85 rc = _wstati64(zMbcs+4, buf);
86 }
87 }else{
88 rc = _wstati64(zMbcs, buf);
89 }
90 #endif
91 fossil_filename_free(zMbcs);
92 return rc;
93 }
@@ -314,11 +319,22 @@
314 ** Wrapper around the access() system call.
315 */
316 int file_access(const char *zFilename, int flags){
317 #ifdef _WIN32
318 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
319 int rc = _waccess(zMbcs, flags);
 
 
 
 
 
 
 
 
 
 
 
320 #else
321 char *zMbcs = fossil_utf8_to_filename(zFilename);
322 int rc = access(zMbcs, flags);
323 #endif
324 fossil_filename_free(zMbcs);
@@ -331,11 +347,11 @@
331 ** (UNIX only)
332 */
333 int file_chdir(const char *zChDir, int bChroot){
334 #ifdef _WIN32
335 wchar_t *zPath = fossil_utf8_to_filename(zChDir);
336 int rc = _wchdir(zPath);
337 #else
338 char *zPath = fossil_utf8_to_filename(zChDir);
339 int rc = chdir(zPath);
340 if( !rc && bChroot ){
341 rc = chroot(zPath);
342
--- src/file.c
+++ src/file.c
@@ -47,11 +47,16 @@
47 ** Use _stati64 rather than stat on windows, in order to handle files
48 ** larger than 2GB.
49 */
50 #if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
51 # undef stat
52 # define stat _fossil_stati64
53 struct stat {
54 i64 st_size;
55 i64 st_mtime;
56 int st_mode;
57 };
58 #endif
59 /*
60 ** On Windows S_ISLNK always returns FALSE.
61 */
62 #if !defined(S_ISLNK)
@@ -73,21 +78,21 @@
78 rc = lstat(zMbcs, buf);
79 }else{
80 rc = stat(zMbcs, buf);
81 }
82 #else
83 WIN32_FILE_ATTRIBUTE_DATA attr;
84 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
85 rc = !GetFileAttributesExW(zMbcs, GetFileExInfoStandard, &attr);
86 if( !rc ){
87 ULARGE_INTEGER ull;
88 ull.LowPart = attr.ftLastWriteTime.dwLowDateTime;
89 ull.HighPart = attr.ftLastWriteTime.dwHighDateTime;
90 buf->st_mode = (attr.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)?
91 S_IFDIR:S_IFREG;
92 buf->st_size = (((i64)attr.nFileSizeHigh)<<32) | buf->attr.nFileSizeLow;
93 buf->st_mtime = ull.QuadPart / 10000000ULL - 11644473600ULL;
 
94 }
95 #endif
96 fossil_filename_free(zMbcs);
97 return rc;
98 }
@@ -314,11 +319,22 @@
319 ** Wrapper around the access() system call.
320 */
321 int file_access(const char *zFilename, int flags){
322 #ifdef _WIN32
323 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
324 int rc;
325 if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
326 /* Unfortunately, _waccess cannot handle extended prefixes. */
327 if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
328 zMbcs[6] = '\\';
329 rc = _waccess(zMbcs+6, flags);
330 }else{
331 rc = _waccess(zMbcs+4, flags);
332 }
333 }else{
334 rc = _waccess(zMbcs, flags);
335 }
336 #else
337 char *zMbcs = fossil_utf8_to_filename(zFilename);
338 int rc = access(zMbcs, flags);
339 #endif
340 fossil_filename_free(zMbcs);
@@ -331,11 +347,11 @@
347 ** (UNIX only)
348 */
349 int file_chdir(const char *zChDir, int bChroot){
350 #ifdef _WIN32
351 wchar_t *zPath = fossil_utf8_to_filename(zChDir);
352 int rc = SetCurrentDirectoryW(zPath)==0;
353 #else
354 char *zPath = fossil_utf8_to_filename(zChDir);
355 int rc = chdir(zPath);
356 if( !rc && bChroot ){
357 rc = chroot(zPath);
358

Keyboard Shortcuts

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