Fossil

Check-in [29f023fe53]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | win32-longpath
Files: files | file ages | folders
SHA1: 29f023fe536c49b2bfc222e785b3e5ec6ea1aac5
User & Date: jan.nijtmans 2013-12-12 13:54:20.222
Context
2013-12-12
14:27
Implement file_access() function such that it accepts paths>MAX_PATH. Implementation copied (with some simplifications) from Tcl 8.6 check-in: ba4b3ac1d2 user: jan.nijtmans tags: win32-longpath
13:54
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. check-in: 29f023fe53 user: jan.nijtmans tags: win32-longpath
11:16
Bug-fix: didn't compile on win32, and handle extended UNC paths correctly. check-in: da8d516fe1 user: jan.nijtmans tags: win32-longpath
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/file.c.
45
46
47
48
49
50
51
52





53
54
55
56
57
58
59
** The file status information from the most recent stat() call.
**
** Use _stati64 rather than stat on windows, in order to handle files
** larger than 2GB.
*/
#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
# undef stat
# define stat _stati64





#endif
/*
** On Windows S_ISLNK always returns FALSE.
*/
#if !defined(S_ISLNK)
# define S_ISLNK(x) (0)
#endif







|
>
>
>
>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
** The file status information from the most recent stat() call.
**
** Use _stati64 rather than stat on windows, in order to handle files
** larger than 2GB.
*/
#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
# undef stat
# define stat _fossil_stati64
struct stat {
    i64 st_size;
    i64 st_mtime;
    int st_mode;
};
#endif
/*
** On Windows S_ISLNK always returns FALSE.
*/
#if !defined(S_ISLNK)
# define S_ISLNK(x) (0)
#endif
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
  char *zMbcs = fossil_utf8_to_filename(zFilename);
  if( isWd && g.allowSymlinks ){
    rc = lstat(zMbcs, buf);
  }else{
    rc = stat(zMbcs, buf);
  }
#else

  wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
  if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
    /* Unfortunately, _wstati64 cannot handle extended prefixes. */
    if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
      zMbcs[6] = '\\';
      rc = _wstati64(zMbcs+6, buf);
    }else{
      rc = _wstati64(zMbcs+4, buf);
    }

  }else{
    rc = _wstati64(zMbcs, buf);
  }
#endif
  fossil_filename_free(zMbcs);
  return rc;
}

/*







>

|
<
|
|
|
|
|
<
>
|
|







76
77
78
79
80
81
82
83
84
85

86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
  char *zMbcs = fossil_utf8_to_filename(zFilename);
  if( isWd && g.allowSymlinks ){
    rc = lstat(zMbcs, buf);
  }else{
    rc = stat(zMbcs, buf);
  }
#else
  WIN32_FILE_ATTRIBUTE_DATA attr;
  wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
  rc = !GetFileAttributesExW(zMbcs, GetFileExInfoStandard, &attr);

  if( !rc ){
    ULARGE_INTEGER ull;
    ull.LowPart = attr.ftLastWriteTime.dwLowDateTime;
    ull.HighPart = attr.ftLastWriteTime.dwHighDateTime;
    buf->st_mode = (attr.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)?

                    S_IFDIR:S_IFREG;
    buf->st_size = (((i64)attr.nFileSizeHigh)<<32) | buf->attr.nFileSizeLow;
    buf->st_mtime = ull.QuadPart / 10000000ULL - 11644473600ULL;
  }
#endif
  fossil_filename_free(zMbcs);
  return rc;
}

/*
312
313
314
315
316
317
318










319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

/*
** Wrapper around the access() system call.
*/
int file_access(const char *zFilename, int flags){
#ifdef _WIN32
  wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);










  int rc = _waccess(zMbcs, flags);

#else
  char *zMbcs = fossil_utf8_to_filename(zFilename);
  int rc = access(zMbcs, flags);
#endif
  fossil_filename_free(zMbcs);
  return rc;
}

/*
** Wrapper around the chdir() system call.
** If bChroot=1, do a chroot to this dir as well
** (UNIX only)
*/
int file_chdir(const char *zChDir, int bChroot){
#ifdef _WIN32
  wchar_t *zPath = fossil_utf8_to_filename(zChDir);
  int rc = _wchdir(zPath);
#else
  char *zPath = fossil_utf8_to_filename(zChDir);
  int rc = chdir(zPath);
  if( !rc && bChroot ){
    rc = chroot(zPath);
    if( !rc ) rc = chdir("/");
  }







>
>
>
>
>
>
>
>
>
>
|
>
















|







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

/*
** Wrapper around the access() system call.
*/
int file_access(const char *zFilename, int flags){
#ifdef _WIN32
  wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
  int rc;
  if( memcmp(zMbcs, L"\\\\?\\", 8)==0 ){
    /* Unfortunately, _waccess cannot handle extended prefixes. */
    if( memcmp(zMbcs+4, "UNC\\", 8)==0 ){
      zMbcs[6] = '\\';
      rc = _waccess(zMbcs+6, flags);
    }else{
      rc = _waccess(zMbcs+4, flags);
    }
  }else{
    rc = _waccess(zMbcs, flags);
  }
#else
  char *zMbcs = fossil_utf8_to_filename(zFilename);
  int rc = access(zMbcs, flags);
#endif
  fossil_filename_free(zMbcs);
  return rc;
}

/*
** Wrapper around the chdir() system call.
** If bChroot=1, do a chroot to this dir as well
** (UNIX only)
*/
int file_chdir(const char *zChDir, int bChroot){
#ifdef _WIN32
  wchar_t *zPath = fossil_utf8_to_filename(zChDir);
  int rc = SetCurrentDirectoryW(zPath)==0;
#else
  char *zPath = fossil_utf8_to_filename(zChDir);
  int rc = chdir(zPath);
  if( !rc && bChroot ){
    rc = chroot(zPath);
    if( !rc ) rc = chdir("/");
  }