diff options
author | drh <drh@noemail.net> | 2008-03-27 22:42:51 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2008-03-27 22:42:51 +0000 |
commit | 19db935225bc66eafbc830e3a76262a0d68d870a (patch) | |
tree | d509c76e1bce618ae5be688df7f8d51d1974d1e0 /src | |
parent | 9882d99993685fb111372c9205c2cd83952580a3 (diff) | |
download | sqlite-19db935225bc66eafbc830e3a76262a0d68d870a.tar.gz sqlite-19db935225bc66eafbc830e3a76262a0d68d870a.zip |
Allow the xAccess method in the VFS to return -1 to signal an I/O
error, and in particular an SQLITE_IOERR_NOMEM. (CVS 4925)
FossilOrigin-Name: 3cb704c4c439425781644b1b653b7e50f02fd91e
Diffstat (limited to 'src')
-rw-r--r-- | src/fault.c | 12 | ||||
-rw-r--r-- | src/os.c | 8 | ||||
-rw-r--r-- | src/pager.c | 31 | ||||
-rw-r--r-- | src/pragma.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 17 | ||||
-rw-r--r-- | src/vdbeaux.c | 18 |
6 files changed, 61 insertions, 29 deletions
diff --git a/src/fault.c b/src/fault.c index 7e183ed43..d31dd4387 100644 --- a/src/fault.c +++ b/src/fault.c @@ -42,7 +42,7 @@ static struct FaultInjector { int nBenign; /* Number of benign failures seen since last config */ int nFail; /* Number of failures seen since last config */ u8 enable; /* True if enabled */ - u8 benign; /* Ture if next failure will be benign */ + u8 benign; /* True if next failure will be benign */ } aFault[SQLITE_FAULTINJECTOR_COUNT]; /* @@ -105,8 +105,14 @@ int sqlite3FaultPending(int id){ ** a hash table resize is a benign fault. */ void sqlite3FaultBenign(int id, int enable){ - assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT ); - aFault[id].benign = enable; + if( id<0 ){ + for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){ + aFault[id].benign = enable; + } + }else{ + assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT ); + aFault[id].benign = enable; + } } /* @@ -115,7 +115,13 @@ int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return pVfs->xDelete(pVfs, zPath, dirSync); } int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ - int rc = pVfs->xAccess(pVfs, zPath, flags); + int rc; +#ifdef SQLITE_TEST + void *pTstAlloc = sqlite3_malloc(10); + if (!pTstAlloc) return -1; + sqlite3_free(pTstAlloc); +#endif + rc = pVfs->xAccess(pVfs, zPath, flags); assert( rc==0 || rc==1 ); return rc; } diff --git a/src/pager.c b/src/pager.c index 7f76c13d5..d47321a08 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.420 2008/03/20 11:04:21 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.421 2008/03/27 22:42:52 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1602,7 +1602,12 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ zJournal = zMasterJournal; while( (zJournal-zMasterJournal)<nMasterJournal ){ - if( sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS) ){ + rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS); + if( rc!=0 && rc!=1 ){ + rc = SQLITE_IOERR_NOMEM; + goto delmaster_out; + } + if( rc==1 ){ /* One of the journals pointed to by the master journal exists. ** Open it and check if it points at the master journal. If ** so, return without deleting the master journal file. @@ -1773,12 +1778,10 @@ static int pager_playback(Pager *pPager, int isHot){ */ zMaster = pPager->pTmpSpace; rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK - || (zMaster[0] && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) + || (zMaster[0] && sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)==0 ) ){ zMaster = 0; - if( rc==SQLITE_DONE ) rc = SQLITE_OK; goto end_playback; } pPager->journalOff = 0; @@ -3053,19 +3056,23 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ } /* -** Return TRUE if there is a hot journal on the given pager. +** Return 1 if there is a hot journal on the given pager. ** A hot journal is one that needs to be played back. ** ** If the current size of the database file is 0 but a journal file ** exists, that is probably an old journal left over from a prior ** database with the same name. Just delete the journal. +** +** Return negative if unable to determine the status of the journal. */ static int hasHotJournal(Pager *pPager){ sqlite3_vfs *pVfs = pPager->pVfs; + int rc; if( !pPager->useJournal ) return 0; if( !pPager->fd->pMethods ) return 0; - if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ - return 0; + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS); + if( rc<=0 ){ + return rc; } if( sqlite3OsCheckReservedLock(pPager->fd) ){ return 0; @@ -3365,7 +3372,11 @@ static int pagerSharedLock(Pager *pPager){ /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ - if( hasHotJournal(pPager) || isHot ){ + rc = hasHotJournal(pPager); + if( rc<0 ){ + return pager_error(pPager, SQLITE_IOERR_NOMEM); + } + if( rc==1 || isHot ){ /* Get an EXCLUSIVE lock on the database file. At this point it is ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the @@ -3402,7 +3413,7 @@ static int pagerSharedLock(Pager *pPager){ */ if( !isHot ){ rc = SQLITE_BUSY; - if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ + if( sqlite3OsAccess(pVfs, pPager->zJournal,SQLITE_ACCESS_EXISTS)==1 ){ int fout = 0; int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); diff --git a/src/pragma.c b/src/pragma.c index 8c396b3b4..a712bd869 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.173 2008/03/25 17:23:33 drh Exp $ +** $Id: pragma.c,v 1.174 2008/03/27 22:42:52 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -571,7 +571,7 @@ void sqlite3Pragma( } }else{ if( zRight[0] - && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) + && sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE)==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; diff --git a/src/vdbe.c b/src/vdbe.c index e41c6eed0..61e99978a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.719 2008/03/27 17:59:02 danielk1977 Exp $ +** $Id: vdbe.c,v 1.720 2008/03/27 22:42:52 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -578,8 +578,9 @@ int sqlite3VdbeExec( CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG + sqlite3FaultBenign(-1, 1); if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0 - || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)) + || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)==1 ) ){ int i; printf("VDBE Program Listing:\n"); @@ -588,9 +589,10 @@ int sqlite3VdbeExec( sqlite3VdbePrintOp(stdout, i, &p->aOp[i]); } } - if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS) ){ + if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS)==1 ){ p->trace = stdout; } + sqlite3FaultBenign(-1, 0); #endif for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pc<p->nOp ); @@ -611,9 +613,12 @@ int sqlite3VdbeExec( } sqlite3VdbePrintOp(p->trace, pc, pOp); } - if( p->trace==0 && pc==0 - && sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS) ){ - sqlite3VdbePrintSql(p); + if( p->trace==0 && pc==0 ){ + sqlite3FaultBenign(-1, 1); + if( sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS)==1 ){ + sqlite3VdbePrintSql(p); + } + sqlite3FaultBenign(-1, 0); } #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 369946c4e..ce37808f1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1290,13 +1290,17 @@ static int vdbeCommit(sqlite3 *db){ if( !zMaster ){ return SQLITE_NOMEM; } - }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) ); - - /* Open the master journal. */ - rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| - SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 - ); + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS); + }while( rc==1 ); + if( rc!=0 ){ + rc = SQLITE_IOERR_NOMEM; + }else{ + /* Open the master journal. */ + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 + ); + } if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); return rc; |