From 48a55aa988cdb40046813b57e2b3ff03e680be02 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 7 May 2012 17:16:07 +0000 Subject: [PATCH] Simplify directory checking for winOpen and add checking to winDelete. FossilOrigin-Name: b08530e1a02cba03afefd65dc101e074e8847c07 --- manifest | 19 +++++----- manifest.uuid | 2 +- src/os_win.c | 93 ++++++++++++++++++++++++++++++++++++------------- src/sqlite.h.in | 1 + 4 files changed, 78 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 3527b8bf9f..18cba5b865 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sdo\sthe\sAV\sretry\sloop\son\sopen\sif\sthe\sfile\sthat\sis\sattempting\sto\sbe\nopened\sis\sreally\sa\sdirectory. -D 2012-05-07T13:15:20.389 +C Simplify\sdirectory\schecking\sfor\swinOpen\sand\sadd\schecking\sto\swinDelete. +D 2012-05-07T17:16:07.404 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -160,7 +160,7 @@ F src/os.h 59beba555b65a450bd1d804220532971d4299f60 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 424d46e0edab969293c2223f09923b2178171f47 -F src/os_win.c 5245515000a855dd0fe4f6e86dfe599cd7865b7b +F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c F src/pager.c bb5635dde0b152797836d1c72275284724bb563c F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 F src/parse.y eb054bb40a5bf90d3422a01ed0e5df229461727a @@ -175,7 +175,7 @@ F src/resolve.c 748e75299faff345f34f0e5bd02a2bac8aa69fcd F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1 F src/select.c d7b9018b7dd2e821183d69477ab55c39b8272335 F src/shell.c 04399b2f9942bd02ed5ffee3b84bcdb39c52a1e6 -F src/sqlite.h.in 4338f299fc83dada8407358d585c0e240ecb76a3 +F src/sqlite.h.in b8c6d77179cee6e4b8d6eb9f3c2917626d58acd3 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h c5e917c4f1453f3972b1fd0c81105dfe4f09cc32 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -995,10 +995,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bfa61e781cb442be641486e7e55a1518e888d830 -R 6a3c8de48e2cdbaf71c115aca5627de9 -T *branch * win-check-dir -T *sym-win-check-dir * -T -sym-trunk * -U drh -Z 19d1e551d55fac16aea402b33644e4b5 +P 03875633f465e82fbe99829f96db25f6d32bd333 +R fce36c453dc0cfdd0c18e985348b50c5 +U mistachkin +Z fd728781c5f339cf39ec6076396580d7 diff --git a/manifest.uuid b/manifest.uuid index 24ae4d715c..e5ce37999e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03875633f465e82fbe99829f96db25f6d32bd333 \ No newline at end of file +b08530e1a02cba03afefd65dc101e074e8847c07 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 0f32561937..fcfe0118ed 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3031,27 +3031,33 @@ static int getTempname(int nBuf, char *zBuf){ return SQLITE_OK; } -/* Forward reference */ -static int winAccess(sqlite3_vfs*,const char*,int,int*); - /* ** Return TRUE if the named file is really a directory. Return false if ** it is something other than a directory, or if there is any kind of memory ** allocation failure. */ -static int winIsDir(sqlite3_vfs *pVfs, const char *zName){ - int isDir = 0; - int rc; - char *zDirName; +static int winIsDir(const void *zConverted){ + DWORD attr; + int rc = 0; + DWORD lastErrno; - zDirName = sqlite3_mprintf("%s/nul", zName); - if( zDirName ){ - rc = winAccess(pVfs, zDirName, SQLITE_ACCESS_EXISTS, &isDir); - sqlite3_free(zDirName); + if( isNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} + if( !rc ){ + return 0; /* Invalid name? */ + } + attr = sAttrData.dwFileAttributes; +#if SQLITE_OS_WINCE==0 }else{ - rc = SQLITE_NOMEM; + attr = osGetFileAttributesA((char*)zConverted); +#endif } - return rc==SQLITE_OK && isDir; + return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); } /* @@ -3160,6 +3166,11 @@ static int winOpen( return SQLITE_IOERR_NOMEM; } + if( winIsDir(zConverted) ){ + sqlite3_free(zConverted); + return SQLITE_CANTOPEN_ISDIR; + } + if( isReadWrite ){ dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; }else{ @@ -3208,9 +3219,8 @@ static int winOpen( dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE - && !winIsDir(pVfs, zName) - && retryIoerr(&cnt, &lastErrno) ){ + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt, &lastErrno) ){ /* Noop */ } #if SQLITE_OS_WINCE==0 @@ -3221,7 +3231,9 @@ static int winOpen( dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt, &lastErrno) ){} + retryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } #endif } @@ -3301,6 +3313,7 @@ static int winDelete( ){ int cnt = 0; int rc; + DWORD attr; DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); @@ -3312,20 +3325,50 @@ static int winDelete( return SQLITE_IOERR_NOMEM; } if( isNT() ){ - rc = 1; - while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} - rc = rc ? SQLITE_OK : SQLITE_ERROR; + do { + attr = osGetFileAttributesW(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + rc = SQLITE_OK; /* Already gone? */ + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !retryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - rc = 1; - while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} - rc = rc ? SQLITE_OK : SQLITE_ERROR; + do { + attr = osGetFileAttributesA(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + rc = SQLITE_OK; /* Already gone? */ + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileA(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !retryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); #endif } if( rc ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d10ddaaa20..655f8d2903 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -453,6 +453,7 @@ int sqlite3_exec( #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) -- 2.39.5