mirror of https://github.com/sqlite/sqlite
Trying to get the OS abstraction layer to work. (CVS 256)
FossilOrigin-Name: abff526d005b3b46904de091753cc79548739ad8
This commit is contained in:
parent
db5ed6d55d
commit
8cfbf08ffa
|
@ -61,7 +61,7 @@ ENCODING = @ENCODING@
|
|||
# Object files for the SQLite library.
|
||||
#
|
||||
LIBOBJ = btree.o build.o delete.o expr.o insert.o \
|
||||
main.o pager.o parse.o printf.o random.o select.o table.o \
|
||||
main.o os.o pager.o parse.o printf.o random.o select.o table.o \
|
||||
tokenize.o update.o util.o vdbe.o where.o tclsqlite.o
|
||||
|
||||
# All of the source code files.
|
||||
|
@ -134,6 +134,7 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
|
|||
HDR = \
|
||||
sqlite.h \
|
||||
$(TOP)/src/btree.h \
|
||||
$(TOP)/src/os.h \
|
||||
$(TOP)/src/sqliteInt.h \
|
||||
$(TOP)/src/vdbe.h \
|
||||
parse.h
|
||||
|
@ -150,6 +151,9 @@ main.o: $(TOP)/src/main.c $(HDR)
|
|||
pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
||||
$(TCC) -c $(TOP)/src/pager.c
|
||||
|
||||
os.o: $(TOP)/src/os.c $(HDR)
|
||||
$(TCC) -c $(TOP)/src/os.c
|
||||
|
||||
parse.o: parse.c $(HDR)
|
||||
$(TCC) -c parse.c
|
||||
|
||||
|
|
24
manifest
24
manifest
|
@ -1,6 +1,6 @@
|
|||
C Fix\sa\sproblem\sin\sGROUP\sBY\swith\smultiple\scolumns.\s(CVS\s255)
|
||||
D 2001-09-18T22:17:44
|
||||
F Makefile.in a7053596881af6f2590a816ad4eb8fbbf20724a7
|
||||
C Trying\sto\sget\sthe\sOS\sabstraction\slayer\sto\swork.\s(CVS\s256)
|
||||
D 2001-09-19T13:22:39
|
||||
F Makefile.in 1d9592c4aeedd3643b2e1dfa037ce5faf54805a3
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
F VERSION 3861a21803fcd9eb92a403027b0da2bb7add4de1
|
||||
F configure aad857a97ca28a584228869186eb4cd7dbebbb3a x
|
||||
|
@ -14,15 +14,15 @@ F src/build.c 072d6cf5b894c47d3fb8c11580eaa1a24528bca8
|
|||
F src/delete.c ca7ca9bf8b613730821c4a755030d1a020b5e067
|
||||
F src/expr.c 343a515a4abaf60e9e26c7412aa8c43fd3eae97d
|
||||
F src/insert.c b34860ea58525754f18bde652f74161295ca2455
|
||||
F src/main.c 71ca839b90869c8c13db52fd08b0d0e80dae3288
|
||||
F src/main.c 5e5794eea3316dd3a63c112ccdcc997b9118f345
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/os.c 2e0daeca8a8c75f122d41f894698f5e1b258b69c
|
||||
F src/os.h 3b21772e76df0f3998c5a968a2a0d23b9d4551fe
|
||||
F src/pager.c c7db91e4e44bbf3e13ecea658e47b670d1f26e29
|
||||
F src/os.c 6ed6f61915807b1b4578398b4e797e55b12db4ab
|
||||
F src/os.h 2528414d4d441e86cf458b7520ed7f629d446d70
|
||||
F src/pager.c 28c8a641601b81a11454de3015d3d796e31ea182
|
||||
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||
F src/parse.y 2bcf47bb8e6afd8bc10aebd555fa07b73905bee4
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
F src/random.c 707529bcda5c7382dc32bd0545e0217f90f70e29
|
||||
F src/random.c b6a57e85288470b013ad584a8813e893b60e62fe
|
||||
F src/select.c 7d90a6464906419fde96c0707a4cf4f3280db318
|
||||
F src/shell.c 8e573138074e0b9526fca59b3eac22bdf18ecc03
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
|
@ -35,7 +35,7 @@ F src/test2.c 0168b39225b768cfdadd534406f9dec58c27879e
|
|||
F src/test3.c f46bad555db7a6a25be332a96ac99e4d68a1b0c5
|
||||
F src/tokenize.c 2adf0568edf41b3d3c2fcb541ac49bd6e662da0c
|
||||
F src/update.c a1952ad5d53379fa2b2d12efae5993ddb85a1ddb
|
||||
F src/util.c 2cd0bb9693e1c538a5c6f152b7d45cc8567e6724
|
||||
F src/util.c 2a3491fd761b64cca849b07095076f482d119f9c
|
||||
F src/vdbe.c efe564f482c94d361843c5975e2a5724cf0ca8af
|
||||
F src/vdbe.h 900b59b46afdfb9c048a2a31a4478f380ab8504e
|
||||
F src/where.c cce952b6a2459ac2296e3432876a4252d2fe3b87
|
||||
|
@ -96,7 +96,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
|||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P 8f28a83abac59a2161d486c96386b8df726468d0
|
||||
R 716384b1a17cd98ef2ff77fe086995d1
|
||||
P 22132ce18cad31482cdb9b380cedc3f53bc532b8
|
||||
R f2b9b288263979b8bf39b2aa8c086069
|
||||
U drh
|
||||
Z 8f168bc49c168254b9355cae69013087
|
||||
Z a1f7206e19ddb2d1a7062a107b29fcdc
|
||||
|
|
|
@ -1 +1 @@
|
|||
22132ce18cad31482cdb9b380cedc3f53bc532b8
|
||||
abff526d005b3b46904de091753cc79548739ad8
|
20
src/main.c
20
src/main.c
|
@ -14,12 +14,10 @@
|
|||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.38 2001/09/17 20:25:58 drh Exp $
|
||||
** $Id: main.c,v 1.39 2001/09/19 13:22:40 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
** This is the callback routine for the code that initializes the
|
||||
|
@ -428,8 +426,8 @@ static int sqliteDefaultBusyCallback(
|
|||
const char *NotUsed, /* The name of the table that is busy */
|
||||
int count /* Number of times table has been busy */
|
||||
){
|
||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
int delay = 10000;
|
||||
#if SQLITE_MIN_SLEEP_MS==1
|
||||
int delay = 10;
|
||||
int prior_delay = 0;
|
||||
int timeout = (int)Timeout;
|
||||
int i;
|
||||
|
@ -437,9 +435,9 @@ static int sqliteDefaultBusyCallback(
|
|||
for(i=1; i<count; i++){
|
||||
prior_delay += delay;
|
||||
delay = delay*2;
|
||||
if( delay>=1000000 ){
|
||||
delay = 1000000;
|
||||
prior_delay += 1000000*(count - i - 1);
|
||||
if( delay>=1000 ){
|
||||
delay = 1000;
|
||||
prior_delay += 1000*(count - i - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -447,14 +445,14 @@ static int sqliteDefaultBusyCallback(
|
|||
delay = timeout*1000 - prior_delay;
|
||||
if( delay<=0 ) return 0;
|
||||
}
|
||||
usleep(delay);
|
||||
sqliteOsSleep(delay);
|
||||
return 1;
|
||||
#else
|
||||
int timeout = (int)Timeout;
|
||||
if( (count+1)*1000 > timeout ){
|
||||
return 0;
|
||||
}
|
||||
sleep(1);
|
||||
sqliteOsSleep(1000);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
|
235
src/os.c
235
src/os.c
|
@ -17,6 +17,16 @@
|
|||
#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>
|
||||
|
@ -27,6 +37,44 @@
|
|||
# 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
|
||||
|
@ -41,7 +89,11 @@
|
|||
** 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 ){
|
||||
|
@ -84,6 +136,7 @@ int sqliteOsOpenReadWrite(char *zFilename, OsFile *pResult, int *pReadonly){
|
|||
*pResult = h;
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -97,10 +150,8 @@ int sqliteOsOpenReadWrite(char *zFilename, OsFile *pResult, int *pReadonly){
|
|||
**
|
||||
** 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;
|
||||
|
@ -150,7 +201,7 @@ int sqliteOsTempFileName(char *zBuf){
|
|||
"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;
|
||||
|
@ -181,19 +232,7 @@ int sqliteOsTempFileName(char *zBuf){
|
|||
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;
|
||||
|
@ -214,37 +253,183 @@ int sqliteOsClose(OsFile id){
|
|||
}
|
||||
|
||||
/*
|
||||
** 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
|
||||
}
|
||||
|
|
22
src/os.h
22
src/os.h
|
@ -23,27 +23,35 @@
|
|||
#if OS_UNIX
|
||||
typedef int OsFile;
|
||||
# define SQLITE_TEMPNAME_SIZE 200
|
||||
# if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
# define SQLITE_MIN_SLEEP_MS 1
|
||||
# else
|
||||
# define SQLITE_MIN_SLEEP_MS 1000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if OS_WIN
|
||||
typedef HANDLE OsFile;
|
||||
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+1)
|
||||
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
||||
# deifne SQLITE_MIN_SLEEP_MS 1
|
||||
#endif
|
||||
|
||||
int sqliteOsOpenReadWrite(char*, OsFile*, int*);
|
||||
int sqliteOsOpenExclusive(char*, OsFile*);
|
||||
int sqliteOsDelete(const char*);
|
||||
int sqliteOsFileExists(const char*);
|
||||
int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
|
||||
int sqliteOsOpenExclusive(const char*, OsFile*);
|
||||
int sqliteOsTempFileName(char*);
|
||||
int sqliteOsClose(OsFile);
|
||||
int sqliteOsRead(OsFile, int amt, void*);
|
||||
int sqliteOsWrite(OsFile, int amt, void*);
|
||||
int sqliteOsRead(OsFile, void*, int amt);
|
||||
int sqliteOsWrite(OsFile, const void*, int amt);
|
||||
int sqliteOsSeek(OsFile, int offset);
|
||||
int sqliteOsSync(OsFile);
|
||||
int sqliteOsTruncate(OsFile, int size);
|
||||
int sqliteOsFileSize(OsFile, int *pSize);
|
||||
int sqliteOsLock(OsFile, int wrlock);
|
||||
int sqliteOsUnlock(OsFile);
|
||||
int sqliteOsRandomSeed(int amt, char*);
|
||||
int sqliteSleep(int ms);
|
||||
int sqliteOsRandomSeed(char*);
|
||||
int sqliteOsSleep(int ms);
|
||||
|
||||
|
||||
|
||||
|
|
279
src/pager.c
279
src/pager.c
|
@ -18,13 +18,11 @@
|
|||
** 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>
|
||||
|
||||
|
@ -102,7 +100,8 @@ struct PgHdr {
|
|||
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 */
|
||||
|
@ -172,93 +171,6 @@ static const unsigned char aJournalMagic[] = {
|
|||
# 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.
|
||||
|
@ -304,10 +216,11 @@ static void pager_reset(Pager *pPager){
|
|||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -331,11 +244,11 @@ static int pager_unwritelock(Pager *pPager){
|
|||
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){
|
||||
|
@ -380,7 +293,6 @@ static int pager_playback(Pager *pPager){
|
|||
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)];
|
||||
|
@ -389,26 +301,26 @@ static int pager_playback(Pager *pPager){
|
|||
/* 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.
|
||||
|
@ -417,9 +329,9 @@ static int pager_playback(Pager *pPager){
|
|||
/* 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 */
|
||||
|
@ -436,9 +348,9 @@ static int pager_playback(Pager *pPager){
|
|||
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 ){
|
||||
|
@ -451,30 +363,6 @@ static int pager_playback(Pager *pPager){
|
|||
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.
|
||||
*/
|
||||
|
@ -498,41 +386,37 @@ int sqlitepager_open(
|
|||
){
|
||||
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];
|
||||
|
@ -541,7 +425,7 @@ int sqlitepager_open(
|
|||
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;
|
||||
|
@ -577,16 +461,14 @@ void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -607,11 +489,12 @@ int sqlitepager_close(Pager *pPager){
|
|||
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: {
|
||||
|
@ -623,10 +506,10 @@ int sqlitepager_close(Pager *pPager){
|
|||
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;
|
||||
|
@ -690,14 +573,14 @@ static int syncAllPages(Pager *pPager){
|
|||
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;
|
||||
}
|
||||
|
@ -744,7 +627,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
** 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;
|
||||
}
|
||||
|
@ -752,28 +635,35 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
|
||||
/* 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.
|
||||
|
@ -892,8 +782,8 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||
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);
|
||||
|
@ -1023,20 +913,21 @@ int sqlitepager_write(void *pData){
|
|||
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;
|
||||
|
@ -1044,9 +935,9 @@ int sqlitepager_write(void *pData){
|
|||
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);
|
||||
|
@ -1055,11 +946,11 @@ int sqlitepager_write(void *pData){
|
|||
}
|
||||
}
|
||||
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);
|
||||
|
@ -1110,18 +1001,18 @@ int sqlitepager_commit(Pager *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;
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
** Random numbers are used by some of the database backends in order
|
||||
** to generate random integer keys for tables or random filenames.
|
||||
**
|
||||
** $Id: random.c,v 1.5 2001/09/16 00:13:27 drh Exp $
|
||||
** $Id: random.c,v 1.6 2001/09/19 13:22:40 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <time.h>
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
** Get a single 8-bit random value from the RC4 PRNG.
|
||||
|
@ -48,9 +48,9 @@ int sqliteRandomByte(void){
|
|||
*/
|
||||
if( !prng_state.isInit ){
|
||||
int i;
|
||||
static char seed[] = " sqlite random seed";
|
||||
static char seed[] = " sqlite random seed abcdefghijklmnop";
|
||||
char k[256];
|
||||
time((time_t*)seed);
|
||||
sqliteOsRandomSeed(seed);
|
||||
prng_state.j = 0;
|
||||
prng_state.i = 0;
|
||||
for(i=0; i<256; i++){
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.26 2001/09/18 22:17:44 drh Exp $
|
||||
** $Id: util.c,v 1.27 2001/09/19 13:22:40 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
|
@ -392,7 +392,7 @@ int sqliteHashNoCase(const char *z, int n){
|
|||
int h = 0;
|
||||
if( n<=0 ) n = strlen(z);
|
||||
while( n > 0 ){
|
||||
h = (h<<3) ^ h ^ UpperToLower[*z++];
|
||||
h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++];
|
||||
n--;
|
||||
}
|
||||
if( h<0 ) h = -h;
|
||||
|
|
Loading…
Reference in New Issue