Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -1030,10 +1030,11 @@ if( got==amt ){ return SQLITE_OK; }else if( got<0 ){ return SQLITE_IOERR_READ; }else{ + memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; } } /* Index: src/os_win.c ================================================================== --- src/os_win.c +++ src/os_win.c @@ -1008,10 +1008,11 @@ if( got==(DWORD)amt ){ return SQLITE_OK; }else if( got<0 ){ return SQLITE_IOERR_READ; }else{ + memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; } } /* Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.279 2007/01/03 15:34:30 drh Exp $ +** @(#) $Id: pager.c,v 1.280 2007/01/03 23:36:22 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" @@ -861,10 +861,11 @@ if( !MEMDB ){ sqlite3OsUnlock(pPager->fd, NO_LOCK); pPager->dbSize = -1; } pPager->state = PAGER_UNLOCK; + assert( pPager->pAll==0 ); } /* ** Unlock the database and clear the in-memory cache. This routine @@ -890,11 +891,11 @@ if( pPager->state>=PAGER_RESERVED ){ sqlite3pager_rollback(pPager); } pager_unlock(pPager); pPager->nRef = 0; - assert( pPager->journalOpen==0 ); + assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); } /* ** When this routine is called, the pager has the journal file open and ** a RESERVED or EXCLUSIVE lock on the database. This routine releases @@ -2061,11 +2062,10 @@ ** is made to roll it back. If an error occurs during the rollback ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ int sqlite3pager_close(Pager *pPager){ - PgHdr *pPg, *pNext; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to ** malloc() must have already been made by this thread before it gets ** to this point. This means the ThreadData must have been allocated already ** so that ThreadData.nAlloc can be set. @@ -2073,46 +2073,13 @@ ThreadData *pTsd = sqlite3ThreadData(); assert( pPager ); assert( pTsd && pTsd->nAlloc ); #endif - switch( pPager->state ){ - case PAGER_RESERVED: - case PAGER_SYNCED: - case PAGER_EXCLUSIVE: { - /* We ignore any IO errors that occur during the rollback - ** operation. So disable IO error simulation so that testing - ** works more easily. - */ - disable_simulated_io_errors(); - sqlite3pager_rollback(pPager); - enable_simulated_io_errors(); - pager_unlock(pPager); - assert( pPager->errCode || pPager->journalOpen==0 ); - break; - } - case PAGER_SHARED: { - pager_unlock(pPager); - break; - } - default: { - /* Do nothing */ - break; - } - } - for(pPg=pPager->pAll; pPg; pPg=pNext){ -#ifndef NDEBUG - if( MEMDB ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( !pPg->alwaysRollback ); - assert( !pHist->pOrig ); - assert( !pHist->pStmt ); - } -#endif - pNext = pPg->pNextAll; - sqliteFree(pPg); - } + disable_simulated_io_errors(); + pager_reset(pPager); + enable_simulated_io_errors(); TRACE2("CLOSE %d\n", PAGERID(pPager)); assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); } @@ -2987,11 +2954,11 @@ ** the system will get confused, we have a read-lock on the file and a ** mysterious journal has appeared in the filesystem. */ sqlite3OsDelete(pPager->zJournal); }else{ - pager_unlock(pPager); + pager_reset(pPager); } return rc; } /*