Win32 portability fixes to the 'fileio' extension.
FossilOrigin-Name: 9d2b0f8b84aac862b0572b183e3ba53ea8c0d8742aaa3c3fbe59f6036054fd1a
This commit is contained in:
parent
b5a4a7053b
commit
42a0dbfe92
@ -159,6 +159,97 @@ static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
** This function is designed to convert a Win32 FILETIME structure into the
|
||||
** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
|
||||
*/
|
||||
static sqlite3_uint64 fileTimeToUnixTime(
|
||||
LPFILETIME pFileTime
|
||||
){
|
||||
SYSTEMTIME epochSystemTime;
|
||||
ULARGE_INTEGER epochIntervals;
|
||||
FILETIME epochFileTime;
|
||||
ULARGE_INTEGER fileIntervals;
|
||||
|
||||
memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
|
||||
epochSystemTime.wYear = 1970;
|
||||
epochSystemTime.wMonth = 1;
|
||||
epochSystemTime.wDay = 1;
|
||||
SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
|
||||
epochIntervals.LowPart = epochFileTime.dwLowDateTime;
|
||||
epochIntervals.HighPart = epochFileTime.dwHighDateTime;
|
||||
|
||||
fileIntervals.LowPart = pFileTime->dwLowDateTime;
|
||||
fileIntervals.HighPart = pFileTime->dwHighDateTime;
|
||||
|
||||
return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function attempts to normalize the time values found in the stat()
|
||||
** buffer to UTC. This is necessary on Win32, where the runtime library
|
||||
** appears to return these values as local times.
|
||||
*/
|
||||
static void statTimesToUtc(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
HANDLE hFindFile;
|
||||
WIN32_FIND_DATAW fd;
|
||||
LPWSTR zUnicodeName;
|
||||
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
|
||||
zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( zUnicodeName ){
|
||||
memset(&fd, 0, sizeof(WIN32_FIND_DATA));
|
||||
hFindFile = FindFirstFileW(zUnicodeName, &fd);
|
||||
if( hFindFile!=NULL ){
|
||||
pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
|
||||
pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
|
||||
pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
|
||||
FindClose(hFindFile);
|
||||
}
|
||||
sqlite3_free(zUnicodeName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This function is used in place of stat(). On Windows, special handling
|
||||
** is required in order for the included time to be returned as UTC. On all
|
||||
** other systems, this function simply calls stat().
|
||||
*/
|
||||
static int fileStat(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
#if defined(_WIN32)
|
||||
int rc = stat(zPath, pStatBuf);
|
||||
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
|
||||
return rc;
|
||||
#else
|
||||
return stat(zPath, pStatBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used in place of lstat(). On Windows, special handling
|
||||
** is required in order for the included time to be returned as UTC. On all
|
||||
** other systems, this function simply calls lstat().
|
||||
*/
|
||||
static int fileLinkStat(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
#if defined(_WIN32)
|
||||
int rc = lstat(zPath, pStatBuf);
|
||||
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
|
||||
return rc;
|
||||
#else
|
||||
return lstat(zPath, pStatBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument zFile is the name of a file that will be created and/or written
|
||||
** by SQL function writefile(). This function ensures that the directory
|
||||
@ -190,7 +281,7 @@ static int makeDirectory(
|
||||
if( i==nCopy ) break;
|
||||
zCopy[i] = '\0';
|
||||
|
||||
rc2 = stat(zCopy, &sStat);
|
||||
rc2 = fileStat(zCopy, &sStat);
|
||||
if( rc2!=0 ){
|
||||
if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
|
||||
}else{
|
||||
@ -232,7 +323,7 @@ static int writeFile(
|
||||
** to do so using chmod(), it is not an error. */
|
||||
struct stat sStat;
|
||||
if( errno!=EEXIST
|
||||
|| 0!=stat(zFile, &sStat)
|
||||
|| 0!=fileStat(zFile, &sStat)
|
||||
|| !S_ISDIR(sStat.st_mode)
|
||||
|| ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
|
||||
){
|
||||
@ -279,6 +370,9 @@ static int writeFile(
|
||||
lastWrite.dwLowDateTime = (DWORD)intervals;
|
||||
lastWrite.dwHighDateTime = intervals >> 32;
|
||||
zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
|
||||
if( zUnicodeName==0 ){
|
||||
return 1;
|
||||
}
|
||||
hFile = CreateFileW(
|
||||
zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS, NULL
|
||||
@ -291,7 +385,7 @@ static int writeFile(
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
#elif defined(AT_FDCWD) && 0 /* utimensat() is not univerally available */
|
||||
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
|
||||
/* Recent unix */
|
||||
struct timespec times[2];
|
||||
times[0].tv_nsec = times[1].tv_nsec = 0;
|
||||
@ -568,7 +662,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
|
||||
sqlite3_free(pCur->zPath);
|
||||
pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
|
||||
if( pCur->zPath==0 ) return SQLITE_NOMEM;
|
||||
if( lstat(pCur->zPath, &pCur->sStat) ){
|
||||
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
|
||||
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@ -702,7 +796,7 @@ static int fsdirFilter(
|
||||
if( pCur->zPath==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( lstat(pCur->zPath, &pCur->sStat) ){
|
||||
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
|
||||
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Enable\smore\s'zipfile'\stests\son\sWin32.
|
||||
D 2018-03-16T23:54:26.457
|
||||
C Win32\sportability\sfixes\sto\sthe\s'fileio'\sextension.
|
||||
D 2018-03-16T23:54:36.667
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3
|
||||
@ -277,7 +277,7 @@ F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f0
|
||||
F ext/misc/csv.c 1a009b93650732e22334edc92459c4630b9fa703397cbb3c8ca279921a36ca11
|
||||
F ext/misc/dbdump.c 22018e00eb50e9ebf9067c92d4e7162dc5006a3efc4e0c19bc3829825a1043b0
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c 673d6bde25cab00ad40cc95b89fa99c9f00870c565de3beaab9d6a9658bbc3e0
|
||||
F ext/misc/fileio.c da441efc13c0fa96a41b168bb8aa1014b12d36f3a0d619a2b77b3bdf2a3ccf5e
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984
|
||||
@ -1712,7 +1712,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P bc2af8e0aa28d8d10612ab9464c008a970348b4720bb34d0c546d341e2bc09e0
|
||||
R 7a8f6991afcb70824bbbe5f92582fa58
|
||||
P 49d2566c8e7d0df37494ee001fc6eae5f47f95e16f6a575f2d8d6777b62e6068
|
||||
R 2df366b18e22b23cff08d7e7d1c0c31e
|
||||
U mistachkin
|
||||
Z 9baa572ff0bb0d7155a0ba438dc60407
|
||||
Z 0697d74ec8216cbe655401008c52a666
|
||||
|
@ -1 +1 @@
|
||||
49d2566c8e7d0df37494ee001fc6eae5f47f95e16f6a575f2d8d6777b62e6068
|
||||
9d2b0f8b84aac862b0572b183e3ba53ea8c0d8742aaa3c3fbe59f6036054fd1a
|
Loading…
x
Reference in New Issue
Block a user