/* ** Open an jt file handle. */ static int jtOpen( sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ int rc; jt_file *p = (jt_file *)pFile; pFile->pMethods = 0; p->pReal = (sqlite3_file *)&p[1]; p->pReal->pMethods = 0; rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags); assert( rc==SQLITE_OK || p->pReal->pMethods==0 ); if( rc==SQLITE_OK ){ pFile->pMethods = &jt_io_methods; p->eLock = 0; p->zName = zName; p->flags = flags; p->pNext = 0; p->pWritable = 0; p->aCksum = 0; enterJtMutex(); if( zName ){ p->pNext = g.pList; g.pList = p; } leaveJtMutex(); } return rc; }
/* ** Open a crash-file file handle. ** ** The caller will have allocated pVfs->szOsFile bytes of space ** at pFile. This file uses this space for the CrashFile structure ** and allocates space for the "real" file structure using ** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is ** equal or greater than sizeof(CrashFile). */ static int cfOpen( sqlite3_vfs *pCfVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; int rc; CrashFile *pWrapper = (CrashFile *)pFile; sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1]; memset(pWrapper, 0, sizeof(CrashFile)); rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags); if( rc==SQLITE_OK ){ i64 iSize; pWrapper->pMethod = &CrashFileVtab; pWrapper->zName = (char *)zName; pWrapper->pRealFile = pReal; rc = sqlite3OsFileSize(pReal, &iSize); pWrapper->iSize = (int)iSize; pWrapper->flags = flags; } if( rc==SQLITE_OK ){ pWrapper->nData = (4096 + pWrapper->iSize); pWrapper->zData = crash_malloc(pWrapper->nData); if( pWrapper->zData ){ /* os_unix.c contains an assert() that fails if the caller attempts ** to read data from the 512-byte locking region of a file opened ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file ** never contains valid data anyhow. So avoid doing such a read here. */ const int isDb = (flags&SQLITE_OPEN_MAIN_DB); i64 iChunk = pWrapper->iSize; if( iChunk>PENDING_BYTE && isDb ){ iChunk = PENDING_BYTE; } memset(pWrapper->zData, 0, pWrapper->nData); rc = sqlite3OsRead(pReal, pWrapper->zData, iChunk, 0); if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){ i64 iOff = PENDING_BYTE+512; iChunk = pWrapper->iSize - iOff; rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], iChunk, iOff); } }else{ rc = SQLITE_NOMEM; } } if( rc!=SQLITE_OK && pWrapper->pMethod ){ sqlite3OsClose(pFile); } return rc; }
/* ** Open a crash-file file handle. ** ** The caller will have allocated pVfs->szOsFile bytes of space ** at pFile. This file uses this space for the CrashFile structure ** and allocates space for the "real" file structure using ** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is ** equal or greater than sizeof(CrashFile). */ static int cfOpen( sqlite3_vfs *pCfVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; int rc; CrashFile *pWrapper = (CrashFile *)pFile; sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1]; memset(pWrapper, 0, sizeof(CrashFile)); rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags); if( rc==SQLITE_OK ){ i64 iSize; pWrapper->pMethod = &CrashFileVtab; pWrapper->zName = (char *)zName; pWrapper->pRealFile = pReal; rc = sqlite3OsFileSize(pReal, &iSize); pWrapper->iSize = (int)iSize; pWrapper->flags = flags; } if( rc==SQLITE_OK ){ pWrapper->nData = (int)(4096 + pWrapper->iSize); pWrapper->zData = crash_malloc(pWrapper->nData); if( pWrapper->zData ){ /* os_unix.c contains an assert() that fails if the caller attempts ** to read data from the 512-byte locking region of a file opened ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file ** never contains valid data anyhow. So avoid doing such a read here. ** ** UPDATE: It also contains an assert() verifying that each call ** to the xRead() method reads less than 128KB of data. */ i64 iOff; memset(pWrapper->zData, 0, pWrapper->nData); for(iOff=0; iOff<pWrapper->iSize; iOff += 512){ int nRead = (int)(pWrapper->iSize - iOff); if( nRead>512 ) nRead = 512; rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff); } }else{ rc = SQLITE_NOMEM; } } if( rc!=SQLITE_OK && pWrapper->pMethod ){ sqlite3OsClose(pFile); } return rc; }
/* ** Open an devsym file handle. */ static int devsymOpen( sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ devsym_file *p = (devsym_file *)pFile; pFile->pMethods = &devsym_io_methods; p->pReal = (sqlite3_file *)&p[1]; return sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags); }
void VfsOpenTempFileFileIoErrTest() { //Delete all temp files in this test private data cage. TInt err = DoDeleteTempFiles(); TEST(err == KErrNone || err == KErrNotFound); sqlite3_vfs* vfs = sqlite3_vfs_find(NULL); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); err = SQLITE_ERROR; TInt cnt = 1; while(err != SQLITE_OK) { TInt processHandleCnt = 0; TInt threadHandleCnt = 0; RThread().HandleCount(processHandleCnt, threadHandleCnt); TInt allocCellsCnt = User::CountAllocCells(); TheTest.Printf(_L("%d "), cnt); (void)TheFs.SetErrorCondition(KErrGeneral, cnt); int outFlags = 0; err = sqlite3OsOpen(vfs, NULL, osFile, SQLITE_OPEN_READWRITE, &outFlags); if(err == SQLITE_OK) { //Since this is a temp file, its creation will be delayed till the first file write operation. err = sqlite3OsWrite(osFile, "1234", 4, 0); (void)sqlite3OsClose(osFile); } (void)TheFs.SetErrorCondition(KErrNone); if(err != SQLITE_OK) { TInt processHandleCnt2 = 0; TInt threadHandleCnt2 = 0; RThread().HandleCount(processHandleCnt2, threadHandleCnt2); TEST2(processHandleCnt2, processHandleCnt); TEST2(threadHandleCnt2, threadHandleCnt); TInt allocCellsCnt2 = User::CountAllocCells(); TEST2(allocCellsCnt2, allocCellsCnt); ++cnt; } //If the iteration has failed, then no temp file should exist in the test private data cage. //If the iteration has succeeded, then sqlite3OsClose() should have deleted the temp file. TInt err2 = DoDeleteTempFiles(); TEST2(err2, KErrNotFound); } TEST2(err, SQLITE_OK); TheTest.Printf(_L("\r\n=== TVfs::Open(<temp file>) file I/O error simulation test succeeded at iteration %d\r\n"), cnt); User::Free(osFile); }
/* ** If it does not already exists, create and populate the on-disk file ** for JournalFile p. */ static int createFile(JournalFile *p){ int rc = SQLITE_OK; if( !p->pReal ){ sqlite3_file *pReal = (sqlite3_file *)&p[1]; rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0); if( rc==SQLITE_OK ){ p->pReal = pReal; if( p->iSize>0 ){ assert(p->iSize<=p->nBuf); rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0); } } } return rc; }
//Lock/unlock tests void Test5() { sqlite3_vfs* vfs = sqlite3_vfs_find(KSymbianVfsNameZ); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); //Creating a new file int res = 0; int err = sqlite3OsAccess(vfs, KTestFile1Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); err = sqlite3OsOpen(vfs, KTestFile1Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); TEST2(err, SQLITE_OK); //Lock/unlock //SHARED_LOCK err = sqlite3OsLock(osFile, SHARED_LOCK); TEST2(err, SQLITE_OK); err = sqlite3OsCheckReservedLock(osFile, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); //RESERVED_LOCK err = sqlite3OsLock(osFile, RESERVED_LOCK); TEST2(err, SQLITE_OK); err = sqlite3OsCheckReservedLock(osFile, &res); TEST2(err, SQLITE_OK); TEST2(res, 1); //PENDING_LOCK err = sqlite3OsLock(osFile, PENDING_LOCK); TEST2(err, SQLITE_OK); //EXCLUSIVE_LOCK err = sqlite3OsLock(osFile, EXCLUSIVE_LOCK); TEST2(err, SQLITE_OK); //back to SHARED_LOCK err = sqlite3OsLock(osFile, SHARED_LOCK); TEST2(err, SQLITE_OK); //UNLOCK err = sqlite3OsUnlock(osFile, NO_LOCK); //Close the file err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); // err = sqlite3OsDelete(vfs, KTestFile1Z, 0); TEST2(err, SQLITE_OK); User::Free(osFile); }
void VfsOpenTempFileOomTest() { //Delete all temp files in this test private data cage. TInt err = DoDeleteTempFiles(); TEST(err == KErrNone || err == KErrNotFound); sqlite3_vfs* vfs = sqlite3_vfs_find(NULL); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); TheTest.Printf(_L("Iteration: ")); TInt failingAllocNum = 0; err = SQLITE_IOERR_NOMEM; while(err == SQLITE_IOERR_NOMEM) { ++failingAllocNum; TheTest.Printf(_L("%d "), failingAllocNum); OomPreStep(failingAllocNum); int outFlags = 0; err = sqlite3OsOpen(vfs, NULL, osFile, SQLITE_OPEN_READWRITE, &outFlags); if(err == SQLITE_OK) { //Since this is a temp file, its creation will be delayed till the first file write operation. err = sqlite3OsWrite(osFile, "1234", 4, 0); (void)sqlite3OsClose(osFile); } OomPostStep(); if(err != SQLITE_OK) { TEST2(err, SQLITE_IOERR_NOMEM); } //If the iteration has failed, then no temp file should exist in the test private data cage. //If the iteration has succeeded, then sqlite3OsClose() should have deleted the temp file. TInt err2 = DoDeleteTempFiles(); TEST2(err2, KErrNotFound); } TEST2(err, SQLITE_OK); TheTest.Printf(_L("\r\n=== TVfs::Open(<temp file>) OOM test succeeded at allcoation %d\r\n"), failingAllocNum); User::Free(osFile); }
int sqlite3OsOpenMalloc( sqlite3_vfs *pVfs, const char *zFile, sqlite3_file **ppFile, int flags, int *pOutFlags ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); if( pFile ){ rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ sqlite3_free(pFile); }else{ *ppFile = pFile; } } return rc; }
/* ** Open a crash-file file handle. ** ** The caller will have allocated pVfs->szOsFile bytes of space ** at pFile. This file uses this space for the CrashFile structure ** and allocates space for the "real" file structure using ** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is ** equal or greater than sizeof(CrashFile). */ static int cfOpen( sqlite3_vfs *pCfVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; int rc; CrashFile *pWrapper = (CrashFile *)pFile; sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1]; memset(pWrapper, 0, sizeof(CrashFile)); rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags); if( rc==SQLITE_OK ){ i64 iSize; pWrapper->pMethod = &CrashFileVtab; pWrapper->zName = (char *)zName; pWrapper->pRealFile = pReal; rc = sqlite3OsFileSize(pReal, &iSize); pWrapper->iSize = (int)iSize; } if( rc==SQLITE_OK ){ pWrapper->nData = (4096 + pWrapper->iSize); pWrapper->zData = sqlite3_malloc(pWrapper->nData); if( pWrapper->zData ){ memset(pWrapper->zData, 0, pWrapper->nData); rc = sqlite3OsRead(pReal, pWrapper->zData, pWrapper->iSize, 0); }else{ rc = SQLITE_NOMEM; } } if( rc!=SQLITE_OK && pWrapper->pMethod ){ sqlite3OsClose(pFile); } return rc; }
void VfsCreateDeleteOnCloseFileOomTest() { sqlite3_vfs* vfs = sqlite3_vfs_find(NULL); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); TheTest.Printf(_L("Iteration: ")); TInt failingAllocNum = 0; TInt err = SQLITE_IOERR_NOMEM; while(err == SQLITE_IOERR_NOMEM) { ++failingAllocNum; TheTest.Printf(_L("%d "), failingAllocNum); OomPreStep(failingAllocNum); int outFlags = 0; err = sqlite3OsOpen(vfs, KTestFile4Z, osFile, SQLITE_OPEN_CREATE | SQLITE_OPEN_DELETEONCLOSE, &outFlags); if(err == SQLITE_OK) { err = sqlite3OsClose(osFile); } OomPostStep(); if(err != SQLITE_OK) { TEST2(err, SQLITE_IOERR_NOMEM); } //Whether the iteration has failed or succeeded, the file should not exist. TPtrC8 ptrname((const TUint8*)KTestFile4Z); TBuf<50> fname; fname.Copy(ptrname); TInt err2 = TheFs.Delete(fname); TEST2(err2, KErrNotFound); } TEST2(err, SQLITE_OK); TheTest.Printf(_L("\r\n=== TVfs::Open(<delete on close file>) OOM test succeeded at allcoation %d\r\n"), failingAllocNum); User::Free(osFile); }
/* ** Open a journal file. */ int sqlite3JournalOpen( sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ const char *zName, /* Name of the journal file */ sqlite3_file *pJfd, /* Preallocated, blank file handle */ int flags, /* Opening flags */ int nBuf /* Bytes buffered before opening the file */ ){ JournalFile *p = (JournalFile *)pJfd; memset(p, 0, sqlite3JournalSize(pVfs)); if( nBuf>0 ){ p->zBuf = sqlite3MallocZero(nBuf); if( !p->zBuf ){ return SQLITE_NOMEM; } }else{ return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); } p->pMethod = &JournalFileMethods; p->nBuf = nBuf; p->flags = flags; p->zJournal = zName; p->pVfs = pVfs; return SQLITE_OK; }
void NegativeTest() { TInt err = sqlite3SymbianLibInit(); TEST2(err, KErrNone); sqlite3_vfs* vfs = sqlite3_vfs_find(KSymbianVfsNameZ); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); //Creating a new file - the name is too long const char* KLongFileNameZ = "c:\\test\\0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789.bin"; int outFlags = 0; err = sqlite3OsOpen(vfs, KLongFileNameZ, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, &outFlags); TEST2(err, SQLITE_CANTOPEN); //Open a file - the name contains the '|', but not at position 0 (private database - bad name) const char* KBadFileNameZ = "c:\\test\\01|23456.bin"; err = sqlite3OsOpen(vfs, KBadFileNameZ, osFile, SQLITE_OPEN_READWRITE, &outFlags); TEST2(err, SQLITE_CANTOPEN); //FullPathName() - the output buffer is too small const char* KFileNameZ = "c:\\test\\0123456.bin"; char buf[5]; err = vfs->xFullPathname(vfs, KFileNameZ, 5, buf); TEST2(err, SQLITE_ERROR); //FullPathName() - NULL output buffer err = vfs->xFullPathname(vfs, KFileNameZ, 5, NULL); TEST2(err, SQLITE_ERROR); //FullPathName() - NULL file name err = vfs->xFullPathname(vfs, NULL, 5, buf); TEST2(err, SQLITE_ERROR); //FullPathName() - the file name is too long err = vfs->xFullPathname(vfs, KLongFileNameZ, 5, buf); TEST2(err, SQLITE_ERROR); //FullPathName() - NULL file name err = vfs->xFullPathname(vfs, NULL, 5, buf); TEST2(err, SQLITE_ERROR); //Dellete file - NULL file name err = vfs->xDelete(vfs, 0, 0); TEST2(err, SQLITE_ERROR); //Delete file - the output buffer for the unicode file name is too small err = vfs->xDelete(vfs, KLongFileNameZ, 0); TEST2(err, SQLITE_ERROR); //Open file - NULL file name - this is a temp file name err = sqlite3OsOpen(vfs, NULL, osFile, SQLITE_OPEN_READWRITE, &outFlags); TEST2(err, SQLITE_OK); err = osFile->pMethods->xClose(osFile); TEST2(err, SQLITE_OK); //xAccess - too long file name int res = -1; err = vfs->xAccess(vfs, KLongFileNameZ, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_IOERR_ACCESS); //xAccess - NULL file name err = vfs->xAccess(vfs, 0, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_IOERR_ACCESS); User::Free(osFile); }
//Read/Write/Seek/Truncate test void Test2() { sqlite3_vfs* vfs = sqlite3_vfs_find(KSymbianVfsNameZ); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); //Creating a new file int err = sqlite3OsDelete(vfs, KTestFile1Z, 0); TEST2(err, SQLITE_OK); int res = 0; err = sqlite3OsAccess(vfs, KTestFile1Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); err = sqlite3OsOpen(vfs, KTestFile1Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); TEST2(err, SQLITE_OK); //Writing at the beginning of the file err = sqlite3OsWrite(osFile, "123456", 6, 0); TEST2(err, SQLITE_OK); //Verify the written data char data[20]; err = sqlite3OsRead(osFile, data, 6, 0); TEST2(err, SQLITE_OK); err = memcmp(data, "123456", 6); TEST2(err, 0); //Writing at beyond the end of the file err = sqlite3OsWrite(osFile, "abcdefgh", 8, 100); TEST2(err, SQLITE_OK); //Verify the written data err = sqlite3OsRead(osFile, data, 8, 100); TEST2(err, SQLITE_OK); err = memcmp(data, "abcdefgh", 8); TEST2(err, 0); //Truncate the file err = sqlite3OsTruncate(osFile, 3); TEST2(err, SQLITE_OK); //Write more data err = sqlite3OsWrite(osFile, "xyz", 3, 3); TEST2(err, SQLITE_OK); //Verify the written data err = sqlite3OsRead(osFile, data, 6, 0); TEST2(err, SQLITE_OK); err = memcmp(data, "123xyz", 6); TEST2(err, 0); //Check the file size TInt64 fileSize = 0; err = sqlite3OsFileSize(osFile, &fileSize); TEST2(err, SQLITE_OK); TEST(fileSize == 6); //FileControl - lock type int lockType = -1; err = osFile->pMethods->xFileControl(osFile, SQLITE_FCNTL_LOCKSTATE, &lockType); TEST2(err, SQLITE_OK); TEST2(lockType, NO_LOCK); //FileControl - set callback - NULL callback err = osFile->pMethods->xFileControl(osFile, KSqlFcntlRegisterFreePageCallback, 0); TEST2(err, SQLITE_ERROR); //FileControl - set callback - invalid callback object TSqlFreePageCallback cbck; err = osFile->pMethods->xFileControl(osFile, KSqlFcntlRegisterFreePageCallback, &cbck); TEST2(err, SQLITE_ERROR); //FileControl - invalid op-code err = osFile->pMethods->xFileControl(osFile, 90234, 0); TEST2(err, SQLITE_ERROR); //Close the file err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); // err = sqlite3OsDelete(vfs, KTestFile1Z, 0); TEST2(err, SQLITE_OK); User::Free(osFile); }
//Create/open/close/delete a file void Test1() { sqlite3_vfs* vfs = sqlite3_vfs_find(KSymbianVfsNameZ); TEST(vfs != NULL); sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile); TEST(osFile != NULL); //Creating a new file int outFlags = 0; int err = sqlite3OsOpen(vfs, KTestFile1Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, &outFlags); TEST2(err, SQLITE_OK); TEST(outFlags & SQLITE_OPEN_READWRITE); err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //Opening an existing file for R/W err = sqlite3OsOpen(vfs, KTestFile1Z, osFile, SQLITE_OPEN_READWRITE, &outFlags); TEST2(err, SQLITE_OK); TEST(outFlags & SQLITE_OPEN_READWRITE); err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //Opening a read-only file err = sqlite3OsOpen(vfs, KTestFile2Z, osFile, SQLITE_OPEN_READWRITE, &outFlags); TEST2(err, SQLITE_OK); TEST(outFlags & SQLITE_OPEN_READONLY); //Truncate a read-only file err = osFile->pMethods->xTruncate(osFile, 0); TEST2(err, SQLITE_IOERR); //xAccess - read-only file int res = 0; err = vfs->xAccess(vfs, KTestFile2Z, SQLITE_ACCESS_READ, &res); TEST2(err, SQLITE_OK); TEST(res != 0); //xAccess - invalid request res = 0; err = vfs->xAccess(vfs, KTestFile2Z, 122, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); // err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //Creating a new file err = sqlite3OsOpen(vfs, KTestFile3Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, &outFlags); TEST2(err, SQLITE_OK); TEST(outFlags & SQLITE_OPEN_READWRITE); err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //Open a file for a read-only access err = sqlite3OsOpen(vfs, KTestFile1Z, osFile, SQLITE_OPEN_READONLY, &outFlags); TEST2(err, SQLITE_OK); TEST(outFlags & SQLITE_OPEN_READONLY); err = sqlite3OsWrite(osFile, "1234", 4, 0); TEST(err != SQLITE_OK); err = sqlite3SymbianLastOsError(); TEST2(err, KErrAccessDenied); err = vfs->xGetLastError(vfs, 0, 0); TEST2(err, 0);//Default implementation err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //Delete KTestFile3Z file err = sqlite3OsDelete(vfs, KTestFile3Z, 0); TEST2(err, SQLITE_OK); res = 0; err = sqlite3OsAccess(vfs, KTestFile3Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); //Open a file for an exclusive access err = sqlite3OsOpen(vfs, KTestFile3Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE, &outFlags); TEST2(err, SQLITE_OK); err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //The file should not exist now err = sqlite3OsAccess(vfs, KTestFile3Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); //Open a file for an exclusive access without deleting it after err = sqlite3OsOpen(vfs, KTestFile3Z, osFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE, &outFlags); TEST2(err, SQLITE_OK); err = sqlite3OsClose(osFile); TEST2(err, SQLITE_OK); //The file should exist now err = sqlite3OsAccess(vfs, KTestFile3Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 1); //Delete KTestFile3Z file err = sqlite3OsDelete(vfs, KTestFile3Z, 0); TEST2(err, SQLITE_OK); err = sqlite3OsAccess(vfs, KTestFile3Z, SQLITE_ACCESS_EXISTS, &res); TEST2(err, SQLITE_OK); TEST2(res, 0); // User::Free(osFile); }
/* ** Open an tvfs file handle. */ static int tvfsOpen( sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ int rc; TestvfsFile *pTestfile = (TestvfsFile *)pFile; TestvfsFd *pFd; Tcl_Obj *pId = 0; Testvfs *p = (Testvfs *)pVfs->pAppData; pFd = (TestvfsFd *)ckalloc(sizeof(TestvfsFd) + PARENTVFS(pVfs)->szOsFile); memset(pFd, 0, sizeof(TestvfsFd) + PARENTVFS(pVfs)->szOsFile); pFd->pShm = 0; pFd->pShmId = 0; pFd->zFilename = zName; pFd->pVfs = pVfs; pFd->pReal = (sqlite3_file *)&pFd[1]; memset(pTestfile, 0, sizeof(TestvfsFile)); pTestfile->pFd = pFd; /* Evaluate the Tcl script: ** ** SCRIPT xOpen FILENAME KEY-VALUE-ARGS ** ** If the script returns an SQLite error code other than SQLITE_OK, an ** error is returned to the caller. If it returns SQLITE_OK, the new ** connection is named "anon". Otherwise, the value returned by the ** script is used as the connection name. */ Tcl_ResetResult(p->interp); if( p->pScript && p->mask&TESTVFS_OPEN_MASK ){ Tcl_Obj *pArg = Tcl_NewObj(); Tcl_IncrRefCount(pArg); if( flags&SQLITE_OPEN_MAIN_DB ){ const char *z = &zName[strlen(zName)+1]; while( *z ){ Tcl_ListObjAppendElement(0, pArg, Tcl_NewStringObj(z, -1)); z += strlen(z) + 1; Tcl_ListObjAppendElement(0, pArg, Tcl_NewStringObj(z, -1)); z += strlen(z) + 1; } } tvfsExecTcl(p, "xOpen", Tcl_NewStringObj(pFd->zFilename, -1), pArg, 0, 0); Tcl_DecrRefCount(pArg); if( tvfsResultCode(p, &rc) ){ if( rc!=SQLITE_OK ) return rc; }else{ pId = Tcl_GetObjResult(p->interp); } } if( (p->mask&TESTVFS_OPEN_MASK) && tvfsInjectIoerr(p) ) return SQLITE_IOERR; if( tvfsInjectCantopenerr(p) ) return SQLITE_CANTOPEN; if( tvfsInjectFullerr(p) ) return SQLITE_FULL; if( !pId ){ pId = Tcl_NewStringObj("anon", -1); } Tcl_IncrRefCount(pId); pFd->pShmId = pId; Tcl_ResetResult(p->interp); rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags); if( pFd->pReal->pMethods ){ sqlite3_io_methods *pMethods; int nByte; if( pVfs->iVersion>1 ){ nByte = sizeof(sqlite3_io_methods); }else{ nByte = offsetof(sqlite3_io_methods, xShmMap); } pMethods = (sqlite3_io_methods *)ckalloc(nByte); memcpy(pMethods, &tvfs_io_methods, nByte); pMethods->iVersion = pVfs->iVersion; if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){ pMethods->xShmUnmap = 0; pMethods->xShmLock = 0; pMethods->xShmBarrier = 0; pMethods->xShmMap = 0; } pFile->pMethods = pMethods; } return rc; }