#include "sqliteInt.h"
#include "os.h"
+#ifndef OS_UNIX
+# ifndef OS_WIN
+# define OS_UNIX 1
+# else
+# define OS_UNIX 0
+# endif
+#endif
+#ifndef OS_WIN
+# define OS_WIN 0
+#endif
#if OS_UNIX
# include <fcntl.h>
# include <sys/stat.h>
# include <winbase.h>
#endif
+/*
+** Delete the named file
+*/
+int sqliteOsDelete(const char *zFilename){
+#if OS_UNIX
+ unlink(zFilename);
+#endif
+#if OS_WIN
+ DeleteFile(zFilename);
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqliteOsFileExists(const char *zFilename){
+#if OS_UNIX
+ return access(zFilename, 0)==0;
+#endif
+#if OS_WIN
+ HANDLE h;
+ h = CreateFile(zBuf,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h!=INVALID_FILE_HANDLE ){
+ CloseHandle(h);
+ return 1;
+ }
+ return 0;
+#endif
+}
+
/*
** Attempt to open a file for both reading and writing. If that
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *pResulst and *pReadonly unchanged.
*/
-int sqliteOsOpenReadWrite(char *zFilename, OsFile *pResult, int *pReadonly){
+int sqliteOsOpenReadWrite(
+ const char *zFilename,
+ OsFile *pResult,
+ int *pReadonly
+){
#if OS_UNIX
int fd = open(zFilename, O_RDWR|O_CREAT, 0644);
if( fd<0 ){
*pResult = h;
return SQLITE_OK;
#endif
+}
/*
**
** On failure, return SQLITE_CANTOPEN.
*/
-int sqliteOsOpenExclusive(char *zFilename, OsFile *pResult){
+int sqliteOsOpenExclusive(const char *zFilename, OsFile *pResult){
#if OS_UNIX
- struct stat buf;
- time_t now;
int fd;
if( access(zFilename, 0)==0 ){
return SQLITE_CANTOPEN;
"0123456789";
int i, j;
struct stat buf;
- char *zDir = ".";
+ const char *zDir = ".";
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
if( stat(azDirs[i], &buf) ) continue;
if( !S_ISDIR(buf.st_mode) ) continue;
zBuf[j++] = zChars[n];
}
zBuf[j] = 0;
- h = CreateFile(zBuf,
- GENERIC_READ,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
- NULL
- );
- if( h!=INVALID_FILE_HANDLE ){
- CloseHandle(h);
- continue;
- }
- break;
+ if( !sqliteOsFileExists(zBuf) ) break;
}
#endif
return SQLITE_OK;
}
/*
-** Read data from a file into a buffer
+** Read data from a file into a buffer. Return the number of
+** bytes actually read.
*/
+int sqliteOsRead(OsFile id, void *pBuf, int amt){
+#if OS_UNIX
+ int got;
+ got = read(id, pBuf, amt);
+ if( got<0 ) got = 0;
+ return got==amt ? SQLITE_OK : SQLITE_IOERR;
+#endif
+#if OS_WIN
+ int got;
+ if( !ReadFile(id, pBuf, amt, &got, 0) ){
+ got = 0;
+ }
+ return got==amt ? SQLITE_OK : SQLITE_IOERR;
+#endif
+}
/*
-** Write data from a buffer into a file
+** Write data from a buffer into a file. Return SQLITE_OK on success
+** or some other error code on failure.
*/
+int sqliteOsWrite(OsFile id, const void *pBuf, int amt){
+#if OS_UNIX
+ int wrote;
+ wrote = write(id, pBuf, amt);
+ if( wrote<amt ) return SQLITE_FULL;
+ return SQLITE_OK;
+#endif
+#if OS_WIN
+ int wrote;
+ if( !WriteFile(id, pBuf, amt, &wrote, 0) || wrote<amt ){
+ return SQLITE_FULL;
+ }
+ return SQLITE_OK;
+#endif
+}
+
/*
** Move the read/write pointer in a file.
*/
+int sqliteOsSeek(OsFile id, int offset){
+#if OS_UNIX
+ lseek(id, offset, SEEK_SET);
+ return SQLITE_OK;
+#endif
+#if OS_WIN
+ SetFilePointer(id, offset, 0, FILE_BEGIN);
+ return SQLITE_OK;
+#endif
+}
+
/*
** Make sure all writes to a particular file are committed to disk.
*/
+int sqliteOsSync(OsFile id){
+#if OS_UNIX
+ return fsync(id)==0 ? SQLITE_OK : SQLITE_IOERR;
+#endif
+#if OS_WIN
+ return FlushFileBuffers(id) ? SQLITE_OK : SQLITE_IOERR;
+#endif
+}
+
/*
** Truncate an open file to a specified size
*/
+int sqliteOsTruncate(OsFile id, int nByte){
+#if OS_UNIX
+ return ftruncate(id, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
+#endif
+#if OS_WIN
+ SetFilePointer(id, nByte, 0, FILE_BEGIN);
+ SetEndOfFile(id);
+ return SQLITE_OK;
+#endif
+}
+
/*
** Determine the current size of a file in bytes
*/
+int sqliteOsFileSize(OsFile id, int *pSize){
+#if OS_UNIX
+ struct stat buf;
+ if( fstat(id, &buf)!=0 ){
+ return SQLITE_IOERR;
+ }
+ *pSize = buf.st_size;
+ return SQLITE_OK;
+#endif
+#if OS_WIN
+ *pSize = GetFileSize(id, 0);
+ return SQLITE_OK;
+#endif
+}
+
/*
** Get a read or write lock on a file.
*/
+int sqliteOsLock(OsFile id, int wrlock){
+#if OS_UNIX
+ int rc;
+ struct flock lock;
+memset(&lock, 0, sizeof(lock));
+ lock.l_type = wrlock ? F_WRLCK : F_RDLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0L;
+ lock.l_len = 1024L;
+printf("LOCK %s %d\n",wrlock?"WRITE":"READ",id);
+ rc = fcntl(id, F_SETLK, &lock);
+fcntl(id, F_GETLK, &lock);
+printf("rc=%d why=%d\n",rc,lock.l_type);
+ return rc==0 ? SQLITE_OK : SQLITE_BUSY;
+#endif
+#if OS_WIN
+ if( !LockFile(id, 0, 0, 1024, 0) ){
+ return SQLITE_BUSY;
+ }
+ return SQLITE_OK;
+#endif
+}
+
/*
** Release the read or write lock from a file.
*/
+int sqliteOsUnlock(OsFile id){
+#if OS_UNIX
+ int rc;
+ struct flock lock;
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0L;
+ lock.l_len = 1L;
+printf("UNLOCK %d\n",id);
+ rc = fcntl(id, F_SETLK, &lock);
+ return rc==0 ? SQLITE_OK : SQLITE_IOERR;
+#endif
+#if OS_WIN
+ return UnlockFile(id, 0, 0, 1024, 0) ? SQLITE_OK : SQLITE_IOERR;
+#endif
+}
+
/*
** Get information to seed the random number generator.
*/
+int sqliteOsRandomSeed(char *zBuf){
+#if OS_UNIX
+ int pid;
+ time((time_t*)zBuf);
+ zBuf += sizeof(time_t);
+ pid = getpid();
+ memcpy(zBuf, &pid, sizeof(pid));
+ zBuf += pid;
+ return SQLITE_OK;
+#endif
+#if OS_WIN
+ GetSystemTime((LPSYSTEMTIME)zBuf);
+ return SQLITE_OK;
+#endif
+}
+
/*
-** Sleep for a little while.
+** Sleep for a little while. Return the amount of time slept.
*/
-
-
-
-#endif /* OS_WIN */
+int sqliteOsSleep(int ms){
+#if OS_UNIX
+#if defined(HAVE_USLEEP) && HAVE_USLEEP
+ usleep(ms*1000);
+ return ms;
+#else
+ sleep((ms+999)/1000);
+ return 1000*((ms+999)/1000);
+#endif
+#endif
+#if OS_WIN
+ Sleep(ms);
+ return ms;
+#endif
+}
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.21 2001/09/18 02:02:23 drh Exp $
+** @(#) $Id: pager.c,v 1.22 2001/09/19 13:22:40 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#include "os.h"
#include <assert.h>
#include <string.h>
struct Pager {
char *zFilename; /* Name of the database file */
char *zJournal; /* Name of the journal file */
- int fd, jfd; /* File descriptors for database and journal */
+ OsFile fd, jfd; /* File descriptors for database and journal */
+ int journalOpen; /* True if journal file descriptors is valid */
int dbSize; /* Number of pages in the file */
int origDbSize; /* dbSize before the current change */
int nExtra; /* Add this many bytes to each in-memory page */
# define REFINFO(X)
#endif
-/*
-** Attempt to acquire a read lock (if wrlock==0) or a write lock (if wrlock==1)
-** on the database file. Return 0 on success and non-zero if the lock
-** could not be acquired.
-*/
-static int pager_lock(int fd, int wrlock){
- int rc;
- struct flock lock;
- lock.l_type = wrlock ? F_WRLCK : F_RDLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = lock.l_len = 0L;
- rc = fcntl(fd, F_SETLK, &lock);
- return rc!=0;
-}
-
-/*
-** Unlock the database file.
-*/
-static int pager_unlock(fd){
- int rc;
- struct flock lock;
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = lock.l_len = 0L;
- rc = fcntl(fd, F_SETLK, &lock);
- return rc!=0;
-}
-
-/*
-** Move the cursor for file descriptor fd to the point whereto from
-** the beginning of the file.
-*/
-static int pager_seek(int fd, off_t whereto){
- /*printf("SEEK to page %d\n", whereto/SQLITE_PAGE_SIZE + 1);*/
- lseek(fd, whereto, SEEK_SET);
- return SQLITE_OK;
-}
-
-/*
-** Truncate the given file so that it contains exactly mxPg pages
-** of data.
-*/
-static int pager_truncate(int fd, Pgno mxPg){
- int rc;
- rc = ftruncate(fd, mxPg*SQLITE_PAGE_SIZE);
- return rc!=0 ? SQLITE_IOERR : SQLITE_OK;
-}
-
-/*
-** Read nBytes of data from fd into pBuf. If the data cannot be
-** read or only a partial read occurs, then the unread parts of
-** pBuf are filled with zeros and this routine returns SQLITE_IOERR.
-** If the read is completely successful, return SQLITE_OK.
-*/
-static int pager_read(int fd, void *pBuf, int nByte){
- int rc;
- /* printf("READ\n");*/
- rc = read(fd, pBuf, nByte);
- if( rc<0 ){
- memset(pBuf, 0, nByte);
- return SQLITE_IOERR;
- }
- if( rc<nByte ){
- memset(&((char*)pBuf)[rc], 0, nByte - rc);
- rc = SQLITE_IOERR;
- }else{
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Write nBytes of data into fd. If any problem occurs or if the
-** write is incomplete, SQLITE_IOERR is returned. SQLITE_OK is
-** returned upon complete success.
-*/
-static int pager_write(int fd, const void *pBuf, int nByte){
- int rc;
- /*printf("WRITE\n");*/
- rc = write(fd, pBuf, nByte);
- if( rc<nByte ){
- return SQLITE_FULL;
- }else{
- return SQLITE_OK;
- }
-}
-
/*
** Convert the bits in the pPager->errMask into an approprate
** return code.
if( pPager->state==SQLITE_WRITELOCK ){
sqlitepager_rollback(pPager);
}
- pager_unlock(pPager->fd);
+ sqliteOsUnlock(pPager->fd);
pPager->state = SQLITE_UNLOCK;
pPager->dbSize = -1;
pPager->nRef = 0;
+ assert( pPager->journalOpen==0 );
}
/*
int rc;
PgHdr *pPg;
if( pPager->state!=SQLITE_WRITELOCK ) return SQLITE_OK;
- pager_unlock(pPager->fd);
- rc = pager_lock(pPager->fd, 0);
- unlink(pPager->zJournal);
- close(pPager->jfd);
- pPager->jfd = -1;
+ sqliteOsUnlock(pPager->fd);
+ rc = sqliteOsLock(pPager->fd, 0);
+ sqliteOsClose(pPager->jfd);
+ pPager->journalOpen = 0;
+ sqliteOsDelete(pPager->zJournal);
sqliteFree( pPager->aInJournal );
pPager->aInJournal = 0;
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
int nRec; /* Number of Records */
int i; /* Loop counter */
Pgno mxPg = 0; /* Size of the original file in pages */
- struct stat statbuf; /* Used to size the journal */
PgHdr *pPg; /* An existing page in the cache */
PageRecord pgRec;
unsigned char aMagic[sizeof(aJournalMagic)];
/* Read the beginning of the journal and truncate the
** database file back to its original size.
*/
- assert( pPager->jfd>=0 );
- pager_seek(pPager->jfd, 0);
- rc = pager_read(pPager->jfd, aMagic, sizeof(aMagic));
+ assert( pPager->journalOpen );
+ sqliteOsSeek(pPager->jfd, 0);
+ rc = sqliteOsRead(pPager->jfd, aMagic, sizeof(aMagic));
if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
return SQLITE_PROTOCOL;
}
- rc = pager_read(pPager->jfd, &mxPg, sizeof(mxPg));
+ rc = sqliteOsRead(pPager->jfd, &mxPg, sizeof(mxPg));
if( rc!=SQLITE_OK ){
return SQLITE_PROTOCOL;
}
- pager_truncate(pPager->fd, mxPg);
+ sqliteOsTruncate(pPager->fd, mxPg*SQLITE_PAGE_SIZE);
pPager->dbSize = mxPg;
/* Begin reading the journal beginning at the end and moving
** toward the beginning.
*/
- if( fstat(pPager->jfd, &statbuf)!=0 ){
+ if( sqliteOsFileSize(pPager->jfd, &nRec)!=SQLITE_OK ){
return SQLITE_OK;
}
- nRec = (statbuf.st_size - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
+ nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
/* Process segments beginning with the last and working backwards
** to the first.
/* Seek to the beginning of the segment */
off_t ofst;
ofst = i*sizeof(PageRecord) + sizeof(aMagic) + sizeof(Pgno);
- rc = pager_seek(pPager->jfd, ofst);
+ rc = sqliteOsSeek(pPager->jfd, ofst);
if( rc!=SQLITE_OK ) break;
- rc = pager_read(pPager->jfd, &pgRec, sizeof(pgRec));
+ rc = sqliteOsRead(pPager->jfd, &pgRec, sizeof(pgRec));
if( rc!=SQLITE_OK ) break;
/* Sanity checking on the page */
memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
}
- rc = pager_seek(pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
+ rc = sqliteOsSeek(pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) break;
- rc = pager_write(pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
+ rc = sqliteOsWrite(pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) break;
}
if( rc!=SQLITE_OK ){
return rc;
}
-/*
-** Locate a directory where we can potentially create a temporary
-** file.
-*/
-static const char *findTempDir(void){
- static const char *azDirs[] = {
- ".",
- "/var/tmp",
- "/usr/tmp",
- "/tmp",
- "/temp",
- "./temp",
- };
- int i;
- struct stat buf;
- for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
- if( stat(azDirs[i], &buf) ) continue;
- if( !S_ISDIR(buf.st_mode) ) continue;
- if( access(azDirs[i], 07) ) continue;
- return azDirs[i];
- }
- return 0;
-}
-
/*
** Change the maximum number of in-memory pages that are allowed.
*/
){
Pager *pPager;
int nameLen;
- int fd;
+ OsFile fd;
+ int rc;
int tempFile;
int readOnly = 0;
- char zTemp[300];
+ char zTemp[SQLITE_TEMPNAME_SIZE];
*ppPager = 0;
if( sqlite_malloc_failed ){
return SQLITE_NOMEM;
}
if( zFilename ){
- fd = open(zFilename, O_RDWR|O_CREAT, 0644);
- if( fd<0 ){
- fd = open(zFilename, O_RDONLY, 0);
- readOnly = 1;
- }
+ rc = sqliteOsOpenReadWrite(zFilename, &fd, &readOnly);
tempFile = 0;
}else{
int cnt = 8;
- const char *zDir = findTempDir();
- if( zDir==0 ) return SQLITE_CANTOPEN;
+ sqliteOsTempFileName(zTemp);
do{
cnt--;
- sprintf(zTemp,"%s/_sqlite_%u", zDir, (unsigned)sqliteRandomInteger());
- fd = open(zTemp, O_RDWR|O_CREAT|O_EXCL, 0600);
- }while( cnt>0 && fd<0 );
+ sqliteOsTempFileName(zTemp);
+ rc = sqliteOsOpenExclusive(zTemp, &fd);
+ }while( cnt>0 && rc!=SQLITE_OK );
zFilename = zTemp;
tempFile = 1;
}
- if( fd<0 ){
+ if( rc!=SQLITE_OK ){
return SQLITE_CANTOPEN;
}
nameLen = strlen(zFilename);
pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
if( pPager==0 ){
- close(fd);
+ sqliteOsClose(fd);
return SQLITE_NOMEM;
}
pPager->zFilename = (char*)&pPager[1];
strcpy(pPager->zJournal, zFilename);
strcpy(&pPager->zJournal[nameLen], "-journal");
pPager->fd = fd;
- pPager->jfd = -1;
+ pPager->journalOpen = 0;
pPager->nRef = 0;
pPager->dbSize = -1;
pPager->nPage = 0;
*/
int sqlitepager_pagecount(Pager *pPager){
int n;
- struct stat statbuf;
assert( pPager!=0 );
if( pPager->dbSize>=0 ){
return pPager->dbSize;
}
- if( fstat(pPager->fd, &statbuf)!=0 ){
- n = 0;
- }else{
- n = statbuf.st_size/SQLITE_PAGE_SIZE;
+ if( sqliteOsFileSize(pPager->fd, &n)!=SQLITE_OK ){
+ return 0;
}
+ n /= SQLITE_PAGE_SIZE;
if( pPager->state!=SQLITE_UNLOCK ){
pPager->dbSize = n;
}
switch( pPager->state ){
case SQLITE_WRITELOCK: {
sqlitepager_rollback(pPager);
- pager_unlock(pPager->fd);
+ sqliteOsUnlock(pPager->fd);
+ assert( pPager->journalOpen==0 );
break;
}
case SQLITE_READLOCK: {
- pager_unlock(pPager->fd);
+ sqliteOsUnlock(pPager->fd);
break;
}
default: {
pNext = pPg->pNextAll;
sqliteFree(pPg);
}
- if( pPager->fd>=0 ) close(pPager->fd);
- assert( pPager->jfd<0 );
+ sqliteOsClose(pPager->fd);
+ assert( pPager->journalOpen==0 );
if( pPager->tempFile ){
- unlink(pPager->zFilename);
+ sqliteOsDelete(pPager->zFilename);
}
sqliteFree(pPager);
return SQLITE_OK;
PgHdr *pPg;
int rc = SQLITE_OK;
if( pPager->needSync ){
- rc = fsync(pPager->jfd);
+ rc = sqliteOsSync(pPager->jfd);
if( rc!=0 ) return rc;
pPager->needSync = 0;
}
for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
if( pPg->dirty ){
- pager_seek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
- rc = pager_write(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
+ sqliteOsSeek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
+ rc = sqliteOsWrite(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) break;
pPg->dirty = 0;
}
** on the database file.
*/
if( pPager->nRef==0 ){
- if( pager_lock(pPager->fd, 0)!=0 ){
+ if( sqliteOsLock(pPager->fd, 0)!=SQLITE_OK ){
*ppPage = 0;
return SQLITE_BUSY;
}
/* If a journal file exists, try to play it back.
*/
- if( access(pPager->zJournal,0)==0 ){
- int rc;
+ if( sqliteOsFileExists(pPager->zJournal) ){
+ int rc, readOnly;
/* Open the journal for exclusive access. Return SQLITE_BUSY if
** we cannot get exclusive access to the journal file
*/
- pPager->jfd = open(pPager->zJournal, O_RDONLY, 0);
- if( pPager->jfd<0 || pager_lock(pPager->jfd, 1)!=0 ){
- if( pPager->jfd>=0 ){ close(pPager->jfd); pPager->jfd = -1; }
- pager_unlock(pPager->fd);
+ rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &readOnly);
+ if( rc==SQLITE_OK ){
+ pPager->journalOpen = 1;
+ }
+ if( rc!=SQLITE_OK || sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
+ if( pPager->journalOpen ){
+ sqliteOsClose(pPager->jfd);
+ pPager->journalOpen = 0;
+ }
+ sqliteOsUnlock(pPager->fd);
*ppPage = 0;
return SQLITE_BUSY;
}
/* Get a write lock on the database */
- pager_unlock(pPager->fd);
- if( pager_lock(pPager->fd, 1)!=0 ){
- close(pPager->jfd);
- pPager->jfd = -1;
+ sqliteOsUnlock(pPager->fd);
+ if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){
+ sqliteOsClose(pPager->jfd);
+ pPager->journalOpen = 0;
*ppPage = 0;
return SQLITE_PROTOCOL;
}
+ pPager->state = SQLITE_WRITELOCK;
/* Playback and delete the journal. Drop the database write
** lock and reacquire the read lock.
if( pPager->dbSize<pgno ){
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
}else{
- pager_seek(pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
- pager_read(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
+ sqliteOsSeek(pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
+ sqliteOsRead(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
}
if( pPager->nExtra>0 ){
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
if( pPager->aInJournal==0 ){
return SQLITE_NOMEM;
}
- pPager->jfd = open(pPager->zJournal, O_RDWR|O_CREAT, 0644);
- if( pPager->jfd<0 ){
+ rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd);
+ if( rc!=SQLITE_OK ){
return SQLITE_CANTOPEN;
}
+ pPager->journalOpen = 1;
pPager->needSync = 0;
- if( pager_lock(pPager->jfd, 1) ){
- close(pPager->jfd);
- pPager->jfd = -1;
+ if( sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
+ sqliteOsClose(pPager->jfd);
+ pPager->journalOpen = 0;
return SQLITE_BUSY;
}
- pager_unlock(pPager->fd);
- if( pager_lock(pPager->fd, 1) ){
- close(pPager->jfd);
- pPager->jfd = -1;
+ sqliteOsUnlock(pPager->fd);
+ if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){
+ sqliteOsClose(pPager->jfd);
+ pPager->journalOpen = 0;
pPager->state = SQLITE_UNLOCK;
pPager->errMask |= PAGER_ERR_LOCK;
return SQLITE_PROTOCOL;
pPager->state = SQLITE_WRITELOCK;
sqlitepager_pagecount(pPager);
pPager->origDbSize = pPager->dbSize;
- rc = pager_write(pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
+ rc = sqliteOsWrite(pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
if( rc==SQLITE_OK ){
- rc = pager_write(pPager->jfd, &pPager->dbSize, sizeof(Pgno));
+ rc = sqliteOsWrite(pPager->jfd, &pPager->dbSize, sizeof(Pgno));
}
if( rc!=SQLITE_OK ){
rc = pager_unwritelock(pPager);
}
}
assert( pPager->state==SQLITE_WRITELOCK );
- assert( pPager->jfd>=0 );
+ assert( pPager->journalOpen );
if( pPg->pgno <= pPager->origDbSize ){
- rc = pager_write(pPager->jfd, &pPg->pgno, sizeof(Pgno));
+ rc = sqliteOsWrite(pPager->jfd, &pPg->pgno, sizeof(Pgno));
if( rc==SQLITE_OK ){
- rc = pager_write(pPager->jfd, pData, SQLITE_PAGE_SIZE);
+ rc = sqliteOsWrite(pPager->jfd, pData, SQLITE_PAGE_SIZE);
}
if( rc!=SQLITE_OK ){
sqlitepager_rollback(pPager);
if( pPager->state!=SQLITE_WRITELOCK ){
return SQLITE_ERROR;
}
- assert( pPager->jfd>=0 );
- if( pPager->needSync && fsync(pPager->jfd) ){
+ assert( pPager->journalOpen );
+ if( pPager->needSync && sqliteOsSync(pPager->jfd)!=SQLITE_OK ){
goto commit_abort;
}
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
if( pPg->dirty==0 ) continue;
- rc = pager_seek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
+ rc = sqliteOsSeek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) goto commit_abort;
- rc = pager_write(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
+ rc = sqliteOsWrite(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) goto commit_abort;
}
- if( fsync(pPager->fd) ) goto commit_abort;
+ if( sqliteOsSync(pPager->fd)!=SQLITE_OK ) goto commit_abort;
rc = pager_unwritelock(pPager);
pPager->dbSize = -1;
return rc;