mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Begin migration to using sqlite3_vfs interface. (CVS 4240)
FossilOrigin-Name: af3e3c7acdc67013dd733effebe981620d922dd1
This commit is contained in:
50
manifest
50
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Begin\sadding\smutexes.\s\sCompiles\swithout\sSQLITE_OMIT_SHARED_CACHE\sbut\swe\nget\san\sassertion\sfault\son\sthe\sshared\scache\stesting.\s(CVS\s4239)
|
C Begin\smigration\sto\susing\ssqlite3_vfs\sinterface.\s(CVS\s4240)
|
||||||
D 2007-08-17T01:14:38
|
D 2007-08-17T15:53:36
|
||||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -68,7 +68,7 @@ F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173
|
|||||||
F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
|
F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
|
||||||
F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
|
F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
|
||||||
F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb
|
F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb
|
||||||
F src/btree.c 409e7362338d3cf1f72961a01e75e9fbb577cc9f
|
F src/btree.c c4e563b8a8301413984156909461dea882eabed8
|
||||||
F src/btree.h 91ee529d581c1473d8e6e15299acc3b8de1d0674
|
F src/btree.h 91ee529d581c1473d8e6e15299acc3b8de1d0674
|
||||||
F src/btreeInt.h 6329e955a7dadd8628d5866e2465721b5fd25ef2
|
F src/btreeInt.h 6329e955a7dadd8628d5866e2465721b5fd25ef2
|
||||||
F src/build.c add67be992307b4b11849a6611bfd3352aacde92
|
F src/build.c add67be992307b4b11849a6611bfd3352aacde92
|
||||||
@@ -84,46 +84,46 @@ F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e
|
|||||||
F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
|
F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
|
||||||
F src/legacy.c 6013a7cb7da1b72550b3d35d4fc598b3c3e5b8c1
|
F src/legacy.c 6013a7cb7da1b72550b3d35d4fc598b3c3e5b8c1
|
||||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||||
F src/loadext.c aa1c6e584d39cc241226ec9390387bc2d4a23e8f
|
F src/loadext.c c0ccda3dbda109da087a8fd762deebe5fdf24a1d
|
||||||
F src/main.c 6e12fdab03efb8fb17aee8cfcd3bc32329cf1cda
|
F src/main.c cb6635a4d2fe2b140942338ff5ab605f4c08fa5d
|
||||||
F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1
|
F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/mem1.c 2c6a6e3b2c9c7cb8d398a8468095032407c3e0b7
|
F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
|
||||||
F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea
|
F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea
|
||||||
F src/mutex.c 67b2efd36a1e67a7dc7b7fa852fd69953462c943
|
F src/mutex.c 67b2efd36a1e67a7dc7b7fa852fd69953462c943
|
||||||
F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
|
F src/os.c c8034df18a06cd1e9dde7d6e096b6709345ee72e
|
||||||
F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
|
F src/os.h e54a81bc851724ad17206bfcb4a474f9481f9fc0
|
||||||
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
|
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
|
||||||
F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
|
F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
|
||||||
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
|
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
|
||||||
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
||||||
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
||||||
F src/os_unix.c e685354a7f21cb47741efc6c681c5acea74597fc
|
F src/os_unix.c bf86c474a5febb67684b967a8d2816b1d7f26891
|
||||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||||
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
|
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 812a3f78ea398764991d668d2d3d81a951e58fa3
|
F src/pager.c ee60b932e7b4ba355f2606505415b4d5183b1de1
|
||||||
F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
|
F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
|
||||||
F src/parse.y c03529c3b82702ada98ce405b390e3a9409708cf
|
F src/parse.y c03529c3b82702ada98ce405b390e3a9409708cf
|
||||||
F src/pragma.c 873b0b2ab56248ef76d0387193b8f7a87782b73c
|
F src/pragma.c 8f5e37c3cf6dbdeb3645bb80cc58cfc3324c0178
|
||||||
F src/prepare.c 03292beeffce2d65debab12508a8ec1f5aec7241
|
F src/prepare.c 03292beeffce2d65debab12508a8ec1f5aec7241
|
||||||
F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2
|
F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2
|
||||||
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
|
F src/random.c 00b30565f018f3a256c157432935de070231c73b
|
||||||
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
||||||
F src/sqlite.h.in 07eea55853b739b372d4744ceefd08795d013be9
|
F src/sqlite.h.in f29eb4bc8dc8f4dc61690f339ebb82fec010d4c1
|
||||||
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
||||||
F src/sqliteInt.h 7298c560e00f2305e2ecc1d2cbdd66134f5049de
|
F src/sqliteInt.h 442a6861cf3f535f410acad19a55b2fbca2564a7
|
||||||
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
||||||
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
|
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
|
||||||
F src/tclsqlite.c 0606c4f31711492eb4d7480a981eebb80914f3d9
|
F src/tclsqlite.c 0606c4f31711492eb4d7480a981eebb80914f3d9
|
||||||
F src/test1.c a1d6eb85149053fac75b01b71439f00908a07c68
|
F src/test1.c a226ab03048491aa6c5d43d26097df96bdb162e7
|
||||||
F src/test2.c 4db48e4a487d4d18c2926d9600875613ad286ba8
|
F src/test2.c 47bb59a0198651a9f0551ec956de151da7c24575
|
||||||
F src/test3.c b87e8fcce45e1d3153aae9f04236076b7707a714
|
F src/test3.c b87e8fcce45e1d3153aae9f04236076b7707a714
|
||||||
F src/test4.c d22cb3ab4f9fdfd0a595b70d5328cee923b7322c
|
F src/test4.c d22cb3ab4f9fdfd0a595b70d5328cee923b7322c
|
||||||
F src/test5.c 7bc8a87c2b6fd076ec2ca9972946e71a367883ad
|
F src/test5.c 7bc8a87c2b6fd076ec2ca9972946e71a367883ad
|
||||||
F src/test6.c 14919eef8504da6814db7ab19608c786d836fcb2
|
F src/test6.c 80990810f64ee96ba27cda5c09624bff383caa60
|
||||||
F src/test7.c 91d914c2c2b2806157213f41f4185ad3a4970c07
|
F src/test7.c 91d914c2c2b2806157213f41f4185ad3a4970c07
|
||||||
F src/test8.c 719c284607c1e91a893f5425df1e92b74c859aef
|
F src/test8.c 719c284607c1e91a893f5425df1e92b74c859aef
|
||||||
F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
|
F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
|
||||||
@@ -144,11 +144,11 @@ F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
|
|||||||
F src/utf.c 853f97ce0d3cff8dbaef517a6dc475f7001a67c5
|
F src/utf.c 853f97ce0d3cff8dbaef517a6dc475f7001a67c5
|
||||||
F src/util.c 0273ba16dbf9bab423b1b84c6d548d8f14c25f64
|
F src/util.c 0273ba16dbf9bab423b1b84c6d548d8f14c25f64
|
||||||
F src/vacuum.c f45bd9d3aad8d68bb3b85cf89d7a797be5075fde
|
F src/vacuum.c f45bd9d3aad8d68bb3b85cf89d7a797be5075fde
|
||||||
F src/vdbe.c 10052a4f1e42e629aee0466b40983e2b61e0295a
|
F src/vdbe.c b5cd895a0516466daacc564da332589a903e2eb0
|
||||||
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
|
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
|
||||||
F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
|
F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
|
||||||
F src/vdbeapi.c a503e3762826d55e808b28393ae1d7b0fa36b1e9
|
F src/vdbeapi.c ddfe341249929b89c47a0ff77f8043ef0987612b
|
||||||
F src/vdbeaux.c c6d50887e8f29706ae35b965298e58fa6ba0e9bf
|
F src/vdbeaux.c 6468d5665a3dd932c2e7e4f6b1c0319334b9887a
|
||||||
F src/vdbeblob.c cf9ee3c7d9977cbd896f8b118da4fb4268637f4f
|
F src/vdbeblob.c cf9ee3c7d9977cbd896f8b118da4fb4268637f4f
|
||||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||||
F src/vdbemem.c 019952d44066a24aef70ca8c284cfd2d1073c398
|
F src/vdbemem.c 019952d44066a24aef70ca8c284cfd2d1073c398
|
||||||
@@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 160593dcc5690af715b775c81137c6e09cca6454
|
P 4c1e9ffebe7c611a8b6a89153ae97ab9bca19ea3
|
||||||
R 5d5493a8682338889467b44d542e4cdc
|
R 473ba7528424cad7a8d671117a18b080
|
||||||
U drh
|
U danielk1977
|
||||||
Z d35e1fbff49f629248bfcae9f72cc56d
|
Z ac059cef33a845a67fcbf5f572a89687
|
||||||
|
@@ -1 +1 @@
|
|||||||
4c1e9ffebe7c611a8b6a89153ae97ab9bca19ea3
|
af3e3c7acdc67013dd733effebe981620d922dd1
|
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.399 2007/08/17 01:14:38 drh Exp $
|
** $Id: btree.c,v 1.400 2007/08/17 15:53:36 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -1063,6 +1063,7 @@ int sqlite3BtreeOpen(
|
|||||||
Btree **ppBtree, /* Pointer to new Btree object written here */
|
Btree **ppBtree, /* Pointer to new Btree object written here */
|
||||||
int flags /* Options */
|
int flags /* Options */
|
||||||
){
|
){
|
||||||
|
sqlite3_vfs *pVfs = (pSqlite?pSqlite->pVfs:sqlite3_find_vfs(0));
|
||||||
BtShared *pBt = 0; /* Shared part of btree structure */
|
BtShared *pBt = 0; /* Shared part of btree structure */
|
||||||
Btree *p; /* Handle to return */
|
Btree *p; /* Handle to return */
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
@@ -1137,7 +1138,7 @@ int sqlite3BtreeOpen(
|
|||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto btree_open_out;
|
goto btree_open_out;
|
||||||
}
|
}
|
||||||
rc = sqlite3PagerOpen(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
|
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, EXTRA_SIZE, flags);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
|
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
|
||||||
}
|
}
|
||||||
|
@@ -267,6 +267,7 @@ int sqlite3_load_extension(
|
|||||||
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
|
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
|
||||||
char **pzErrMsg /* Put error message here if not 0 */
|
char **pzErrMsg /* Put error message here if not 0 */
|
||||||
){
|
){
|
||||||
|
sqlite3_vfs *pVfs = db->pVfs;
|
||||||
void *handle;
|
void *handle;
|
||||||
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
||||||
char *zErrmsg = 0;
|
char *zErrmsg = 0;
|
||||||
@@ -289,7 +290,7 @@ int sqlite3_load_extension(
|
|||||||
zProc = "sqlite3_extension_init";
|
zProc = "sqlite3_extension_init";
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = sqlite3OsDlopen(zFile);
|
handle = sqlite3OsDlOpen(pVfs, zFile);
|
||||||
if( handle==0 ){
|
if( handle==0 ){
|
||||||
if( pzErrMsg ){
|
if( pzErrMsg ){
|
||||||
*pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
|
*pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
|
||||||
@@ -297,20 +298,20 @@ int sqlite3_load_extension(
|
|||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
||||||
sqlite3OsDlsym(handle, zProc);
|
sqlite3OsDlSym(pVfs, handle, zProc);
|
||||||
if( xInit==0 ){
|
if( xInit==0 ){
|
||||||
if( pzErrMsg ){
|
if( pzErrMsg ){
|
||||||
*pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
|
*pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
|
||||||
zProc, zFile);
|
zProc, zFile);
|
||||||
}
|
}
|
||||||
sqlite3OsDlclose(handle);
|
sqlite3OsDlClose(pVfs, handle);
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
|
}else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
|
||||||
if( pzErrMsg ){
|
if( pzErrMsg ){
|
||||||
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
|
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
|
||||||
}
|
}
|
||||||
sqlite3_free(zErrmsg);
|
sqlite3_free(zErrmsg);
|
||||||
sqlite3OsDlclose(handle);
|
sqlite3OsDlClose(pVfs, handle);
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +338,7 @@ int sqlite3_load_extension(
|
|||||||
void sqlite3CloseExtensions(sqlite3 *db){
|
void sqlite3CloseExtensions(sqlite3 *db){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<db->nExtension; i++){
|
for(i=0; i<db->nExtension; i++){
|
||||||
sqlite3OsDlclose(db->aExtension[i]);
|
sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
|
||||||
}
|
}
|
||||||
sqlite3_free(db->aExtension);
|
sqlite3_free(db->aExtension);
|
||||||
}
|
}
|
||||||
@@ -372,14 +373,14 @@ static void **aAutoExtension = 0;
|
|||||||
int sqlite3_auto_extension(void *xInit){
|
int sqlite3_auto_extension(void *xInit){
|
||||||
int i;
|
int i;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
sqlite3OsEnterMutex();
|
sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
|
||||||
|
sqlite3_mutex_enter(mutex);
|
||||||
for(i=0; i<nAutoExtension; i++){
|
for(i=0; i<nAutoExtension; i++){
|
||||||
if( aAutoExtension[i]==xInit ) break;
|
if( aAutoExtension[i]==xInit ) break;
|
||||||
}
|
}
|
||||||
if( i==nAutoExtension ){
|
if( i==nAutoExtension ){
|
||||||
nAutoExtension++;
|
int nByte = (++nAutoExtension)*sizeof(aAutoExtension[0]);
|
||||||
aAutoExtension = sqlite3_realloc( aAutoExtension,
|
aAutoExtension = sqlite3_realloc(aAutoExtension, nByte);
|
||||||
nAutoExtension*sizeof(aAutoExtension[0]) );
|
|
||||||
if( aAutoExtension==0 ){
|
if( aAutoExtension==0 ){
|
||||||
nAutoExtension = 0;
|
nAutoExtension = 0;
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
@@ -387,7 +388,7 @@ int sqlite3_auto_extension(void *xInit){
|
|||||||
aAutoExtension[nAutoExtension-1] = xInit;
|
aAutoExtension[nAutoExtension-1] = xInit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3_mutex_leave(mutex);
|
||||||
assert( (rc&0xff)==rc );
|
assert( (rc&0xff)==rc );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -396,11 +397,12 @@ int sqlite3_auto_extension(void *xInit){
|
|||||||
** Reset the automatic extension loading mechanism.
|
** Reset the automatic extension loading mechanism.
|
||||||
*/
|
*/
|
||||||
void sqlite3_reset_auto_extension(void){
|
void sqlite3_reset_auto_extension(void){
|
||||||
sqlite3OsEnterMutex();
|
sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
|
||||||
|
sqlite3_mutex_enter(mutex);
|
||||||
sqlite3_free(aAutoExtension);
|
sqlite3_free(aAutoExtension);
|
||||||
aAutoExtension = 0;
|
aAutoExtension = 0;
|
||||||
nAutoExtension = 0;
|
nAutoExtension = 0;
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3_mutex_leave(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -418,7 +420,8 @@ int sqlite3AutoLoadExtensions(sqlite3 *db){
|
|||||||
}
|
}
|
||||||
for(i=0; go; i++){
|
for(i=0; go; i++){
|
||||||
char *zErrmsg = 0;
|
char *zErrmsg = 0;
|
||||||
sqlite3OsEnterMutex();
|
sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
|
||||||
|
sqlite3_mutex_enter(mutex);
|
||||||
if( i>=nAutoExtension ){
|
if( i>=nAutoExtension ){
|
||||||
xInit = 0;
|
xInit = 0;
|
||||||
go = 0;
|
go = 0;
|
||||||
@@ -426,7 +429,7 @@ int sqlite3AutoLoadExtensions(sqlite3 *db){
|
|||||||
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
||||||
aAutoExtension[i];
|
aAutoExtension[i];
|
||||||
}
|
}
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3_mutex_leave(mutex);
|
||||||
if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
|
if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
|
||||||
sqlite3Error(db, SQLITE_ERROR,
|
sqlite3Error(db, SQLITE_ERROR,
|
||||||
"automatic extension loading failed: %s", zErrmsg);
|
"automatic extension loading failed: %s", zErrmsg);
|
||||||
|
12
src/main.c
12
src/main.c
@@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.383 2007/08/17 01:14:38 drh Exp $
|
** $Id: main.c,v 1.384 2007/08/17 15:53:36 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -304,7 +304,8 @@ static int sqliteDefaultBusyCallback(
|
|||||||
static const u8 totals[] =
|
static const u8 totals[] =
|
||||||
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
|
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
|
||||||
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
|
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
|
||||||
int timeout = ((sqlite3 *)ptr)->busyTimeout;
|
sqlite3 *db = (sqlite3 *)ptr;
|
||||||
|
int timeout = db->busyTimeout;
|
||||||
int delay, prior;
|
int delay, prior;
|
||||||
|
|
||||||
assert( count>=0 );
|
assert( count>=0 );
|
||||||
@@ -319,7 +320,7 @@ static int sqliteDefaultBusyCallback(
|
|||||||
delay = timeout - prior;
|
delay = timeout - prior;
|
||||||
if( delay<=0 ) return 0;
|
if( delay<=0 ) return 0;
|
||||||
}
|
}
|
||||||
sqlite3OsSleep(delay);
|
sqlite3OsSleep(db->pVfs, delay);
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
int timeout = ((sqlite3 *)ptr)->busyTimeout;
|
int timeout = ((sqlite3 *)ptr)->busyTimeout;
|
||||||
@@ -898,6 +899,7 @@ static int openDatabase(
|
|||||||
/* Allocate the sqlite data structure */
|
/* Allocate the sqlite data structure */
|
||||||
db = sqlite3MallocZero( sizeof(sqlite3) );
|
db = sqlite3MallocZero( sizeof(sqlite3) );
|
||||||
if( db==0 ) goto opendb_out;
|
if( db==0 ) goto opendb_out;
|
||||||
|
db->pVfs = sqlite3_find_vfs(0);
|
||||||
db->errMask = 0xff;
|
db->errMask = 0xff;
|
||||||
db->priorNewRowid = 0;
|
db->priorNewRowid = 0;
|
||||||
db->magic = SQLITE_MAGIC_BUSY;
|
db->magic = SQLITE_MAGIC_BUSY;
|
||||||
@@ -1374,7 +1376,9 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
|||||||
** Sleep for a little while. Return the amount of time slept.
|
** Sleep for a little while. Return the amount of time slept.
|
||||||
*/
|
*/
|
||||||
int sqlite3_sleep(int ms){
|
int sqlite3_sleep(int ms){
|
||||||
return sqlite3OsSleep(ms);
|
sqlite3_vfs *pVfs;
|
||||||
|
pVfs = sqlite3_find_vfs(0);
|
||||||
|
return sqlite3OsSleep(pVfs, 1000*ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains the C functions that implement a memory
|
** This file contains the C functions that implement a memory
|
||||||
** allocation subsystem for use by SQLite.
|
** allocation subsystem for use by SQLite.
|
||||||
**
|
**
|
||||||
** $Id: mem1.c,v 1.5 2007/08/16 19:40:17 drh Exp $
|
** $Id: mem1.c,v 1.6 2007/08/17 15:53:36 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -204,7 +204,7 @@ void *sqlite3_realloc(void *pPrior, unsigned int nBytes){
|
|||||||
}
|
}
|
||||||
if( nBytes==0 ){
|
if( nBytes==0 ){
|
||||||
sqlite3_free(pPrior);
|
sqlite3_free(pPrior);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
p = pPrior;
|
p = pPrior;
|
||||||
p--;
|
p--;
|
||||||
|
105
src/os.c
105
src/os.c
@@ -24,16 +24,9 @@
|
|||||||
** of this would be completely automatic if SQLite were coded using
|
** of this would be completely automatic if SQLite were coded using
|
||||||
** C++ instead of plain old C.
|
** C++ instead of plain old C.
|
||||||
*/
|
*/
|
||||||
int sqlite3OsClose(sqlite3_file **pId){
|
int sqlite3OsClose(sqlite3_file *pId){
|
||||||
int rc = SQLITE_OK;
|
if( !pId->pMethods ) return SQLITE_OK;
|
||||||
sqlite3_file *id;
|
return pId->pMethods->xClose(pId);
|
||||||
if( pId!=0 && (id = *pId)!=0 ){
|
|
||||||
rc = id->pMethods->xClose(id);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
*pId = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
|
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
|
||||||
return id->pMethods->xRead(id, pBuf, amt, offset);
|
return id->pMethods->xRead(id, pBuf, amt, offset);
|
||||||
@@ -82,17 +75,83 @@ int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_REDEF_IO
|
int sqlite3OsOpen(
|
||||||
/*
|
sqlite3_vfs *pVfs,
|
||||||
** A function to return a pointer to the virtual function table.
|
const char *zPath,
|
||||||
** This routine really does not accomplish very much since the
|
sqlite3_file *pFile,
|
||||||
** virtual function table is a global variable and anybody who
|
int flags,
|
||||||
** can call this function can just as easily access the variable
|
int *pFlagsOut
|
||||||
** for themselves. Nevertheless, we include this routine for
|
){
|
||||||
** backwards compatibility with an earlier redefinable I/O
|
return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut);
|
||||||
** interface design.
|
|
||||||
*/
|
|
||||||
struct sqlite3OsVtbl *sqlite3_os_switch(void){
|
|
||||||
return &sqlite3Os;
|
|
||||||
}
|
}
|
||||||
#endif
|
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath){
|
||||||
|
return pVfs->xDelete(pVfs->pAppData, zPath);
|
||||||
|
}
|
||||||
|
int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
|
||||||
|
return pVfs->xAccess(pVfs->pAppData, zPath, flags);
|
||||||
|
}
|
||||||
|
int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){
|
||||||
|
return pVfs->xGetTempName(pVfs->pAppData, zBufOut);
|
||||||
|
}
|
||||||
|
int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){
|
||||||
|
return pVfs->xFullPathname(pVfs->pAppData, zPath, zPathOut);
|
||||||
|
}
|
||||||
|
void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
|
||||||
|
return pVfs->xDlOpen(pVfs->pAppData, zPath);
|
||||||
|
}
|
||||||
|
void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
||||||
|
pVfs->xDlError(pVfs->pAppData, nByte, zBufOut);
|
||||||
|
}
|
||||||
|
void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
|
||||||
|
return pVfs->xDlSym(pHandle, zSymbol);
|
||||||
|
}
|
||||||
|
void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||||
|
pVfs->xDlClose(pHandle);
|
||||||
|
}
|
||||||
|
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
||||||
|
return pVfs->xRandomness(pVfs->pAppData, nByte, zBufOut);
|
||||||
|
}
|
||||||
|
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||||
|
return pVfs->xSleep(pVfs->pAppData, nMicro);
|
||||||
|
}
|
||||||
|
int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||||
|
return pVfs->xCurrentTime(pVfs->pAppData, pTimeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sqlite3OsOpenMalloc(
|
||||||
|
sqlite3_vfs *pVfs,
|
||||||
|
const char *zFile,
|
||||||
|
sqlite3_file **ppFile,
|
||||||
|
int flags
|
||||||
|
){
|
||||||
|
int rc = SQLITE_NOMEM;
|
||||||
|
sqlite3_file *pFile;
|
||||||
|
pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
|
||||||
|
if( pFile ){
|
||||||
|
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, 0);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3_free(pFile);
|
||||||
|
}else{
|
||||||
|
*ppFile = pFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
int sqlite3OsCloseFree(sqlite3_file *pFile){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
if( pFile ){
|
||||||
|
rc = sqlite3OsClose(pFile);
|
||||||
|
sqlite3_free(pFile);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Default vfs implementation. Defined by the various os_X.c implementations.
|
||||||
|
*/
|
||||||
|
extern sqlite3_vfs sqlite3DefaultVfs;
|
||||||
|
|
||||||
|
sqlite3_vfs *sqlite3_find_vfs(const char *zVfs){
|
||||||
|
return &sqlite3DefaultVfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
35
src/os.h
35
src/os.h
@@ -121,6 +121,8 @@
|
|||||||
# define TEMP_FILE_PREFIX "etilqs_"
|
# define TEMP_FILE_PREFIX "etilqs_"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Define the interfaces for Unix, Windows, and OS/2.
|
** Define the interfaces for Unix, Windows, and OS/2.
|
||||||
*/
|
*/
|
||||||
@@ -200,6 +202,7 @@
|
|||||||
#define sqlite3OsDlclose sqlite3Os2Dlclose
|
#define sqlite3OsDlclose sqlite3Os2Dlclose
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -346,9 +349,9 @@ extern unsigned int sqlite3_pending_byte;
|
|||||||
#define SHARED_SIZE 510
|
#define SHARED_SIZE 510
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prototypes for operating system interface routines.
|
** Functions for accessing sqlite3_file methods
|
||||||
*/
|
*/
|
||||||
int sqlite3OsClose(sqlite3_file**);
|
int sqlite3OsClose(sqlite3_file*);
|
||||||
int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
|
int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
|
||||||
int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
|
int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
|
||||||
int sqlite3OsTruncate(sqlite3_file*, i64 size);
|
int sqlite3OsTruncate(sqlite3_file*, i64 size);
|
||||||
@@ -361,10 +364,33 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id);
|
|||||||
int sqlite3OsSectorSize(sqlite3_file *id);
|
int sqlite3OsSectorSize(sqlite3_file *id);
|
||||||
int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
|
int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Functions for accessing sqlite3_vfs methods
|
||||||
|
*/
|
||||||
|
int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
|
||||||
|
int sqlite3OsDelete(sqlite3_vfs *, const char *);
|
||||||
|
int sqlite3OsAccess(sqlite3_vfs *, const char *, int);
|
||||||
|
int sqlite3OsGetTempName(sqlite3_vfs *, char *);
|
||||||
|
int sqlite3OsFullPathname(sqlite3_vfs *, const char *, char *);
|
||||||
|
void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
|
||||||
|
void sqlite3OsDlError(sqlite3_vfs *, int, char *);
|
||||||
|
void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);
|
||||||
|
void sqlite3OsDlClose(sqlite3_vfs *, void *);
|
||||||
|
int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
|
||||||
|
int sqlite3OsSleep(sqlite3_vfs *, int);
|
||||||
|
int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convenience functions for opening and closing files using
|
||||||
|
** sqlite3_malloc() to obtain space for the file-handle structure.
|
||||||
|
*/
|
||||||
|
int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int);
|
||||||
|
int sqlite3OsCloseFree(sqlite3_file *);
|
||||||
|
|
||||||
|
#if 0
|
||||||
int sqlite3OsOpenReadWrite(const char*, sqlite3_file**, int*);
|
int sqlite3OsOpenReadWrite(const char*, sqlite3_file**, int*);
|
||||||
int sqlite3OsOpenExclusive(const char*, sqlite3_file**, int);
|
int sqlite3OsOpenExclusive(const char*, sqlite3_file**, int);
|
||||||
int sqlite3OsOpenReadOnly(const char*, sqlite3_file**);
|
int sqlite3OsOpenReadOnly(const char*, sqlite3_file**);
|
||||||
|
|
||||||
int sqlite3OsDelete(const char*);
|
int sqlite3OsDelete(const char*);
|
||||||
int sqlite3OsFileExists(const char*);
|
int sqlite3OsFileExists(const char*);
|
||||||
char *sqlite3OsFullPathname(const char*);
|
char *sqlite3OsFullPathname(const char*);
|
||||||
@@ -385,6 +411,7 @@ int sqlite3OsAllocationSize(void *);
|
|||||||
void *sqlite3OsDlopen(const char*);
|
void *sqlite3OsDlopen(const char*);
|
||||||
void *sqlite3OsDlsym(void*, const char*);
|
void *sqlite3OsDlsym(void*, const char*);
|
||||||
int sqlite3OsDlclose(void*);
|
int sqlite3OsDlclose(void*);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
|
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
|
||||||
int sqlite3OsFileHandle(sqlite3_file *id);
|
int sqlite3OsFileHandle(sqlite3_file *id);
|
||||||
@@ -478,7 +505,7 @@ struct sqlite3OsVtbl {
|
|||||||
sqlite3OsEnterMutex,
|
sqlite3OsEnterMutex,
|
||||||
sqlite3OsLeaveMutex,
|
sqlite3OsLeaveMutex,
|
||||||
sqlite3OsInMutex,
|
sqlite3OsInMutex,
|
||||||
sqlite3OsThreadSpecificData,
|
0,
|
||||||
sqlite3OsMalloc,
|
sqlite3OsMalloc,
|
||||||
sqlite3OsRealloc,
|
sqlite3OsRealloc,
|
||||||
sqlite3OsFree,
|
sqlite3OsFree,
|
||||||
|
585
src/os_unix.c
585
src/os_unix.c
@@ -74,6 +74,10 @@
|
|||||||
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
|
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Maximum supported path-length.
|
||||||
|
*/
|
||||||
|
#define MAX_PATHNAME 512
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -386,6 +390,13 @@ typedef enum {
|
|||||||
} sqlite3LockingStyle;
|
} sqlite3LockingStyle;
|
||||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||||
|
|
||||||
|
static void enterMutex(){
|
||||||
|
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
|
||||||
|
}
|
||||||
|
static void leaveMutex(){
|
||||||
|
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
#ifdef SQLITE_UNIX_THREADS
|
||||||
/*
|
/*
|
||||||
** This variable records whether or not threads can override each others
|
** This variable records whether or not threads can override each others
|
||||||
@@ -529,7 +540,6 @@ static void testThreadLockingBehavior(int fd_orig){
|
|||||||
** Release a lockInfo structure previously allocated by findLockInfo().
|
** Release a lockInfo structure previously allocated by findLockInfo().
|
||||||
*/
|
*/
|
||||||
static void releaseLockInfo(struct lockInfo *pLock){
|
static void releaseLockInfo(struct lockInfo *pLock){
|
||||||
assert( sqlite3OsInMutex(1) );
|
|
||||||
if (pLock == NULL)
|
if (pLock == NULL)
|
||||||
return;
|
return;
|
||||||
pLock->nRef--;
|
pLock->nRef--;
|
||||||
@@ -543,7 +553,6 @@ static void releaseLockInfo(struct lockInfo *pLock){
|
|||||||
** Release a openCnt structure previously allocated by findLockInfo().
|
** Release a openCnt structure previously allocated by findLockInfo().
|
||||||
*/
|
*/
|
||||||
static void releaseOpenCnt(struct openCnt *pOpen){
|
static void releaseOpenCnt(struct openCnt *pOpen){
|
||||||
assert( sqlite3OsInMutex(1) );
|
|
||||||
if (pOpen == NULL)
|
if (pOpen == NULL)
|
||||||
return;
|
return;
|
||||||
pOpen->nRef--;
|
pOpen->nRef--;
|
||||||
@@ -646,7 +655,6 @@ static int findLockInfo(
|
|||||||
rc = fstat(fd, &statbuf);
|
rc = fstat(fd, &statbuf);
|
||||||
if( rc!=0 ) return 1;
|
if( rc!=0 ) return 1;
|
||||||
|
|
||||||
assert( sqlite3OsInMutex(1) );
|
|
||||||
memset(&key1, 0, sizeof(key1));
|
memset(&key1, 0, sizeof(key1));
|
||||||
key1.dev = statbuf.st_dev;
|
key1.dev = statbuf.st_dev;
|
||||||
key1.ino = statbuf.st_ino;
|
key1.ino = statbuf.st_ino;
|
||||||
@@ -820,6 +828,7 @@ static int allocateUnixFile(
|
|||||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||||
** *id and *pReadonly unchanged.
|
** *id and *pReadonly unchanged.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
int sqlite3UnixOpenReadWrite(
|
int sqlite3UnixOpenReadWrite(
|
||||||
const char *zFilename,
|
const char *zFilename,
|
||||||
sqlite3_file **pId,
|
sqlite3_file **pId,
|
||||||
@@ -903,6 +912,7 @@ int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){
|
|||||||
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
|
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Attempt to open a file descriptor for the directory that contains a
|
** Attempt to open a file descriptor for the directory that contains a
|
||||||
@@ -943,46 +953,6 @@ static int unixOpenDirectory(
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Create a temporary file name in zBuf. zBuf must be big enough to
|
|
||||||
** hold at least SQLITE_TEMPNAME_SIZE characters.
|
|
||||||
*/
|
|
||||||
int sqlite3UnixTempFileName(char *zBuf){
|
|
||||||
static const char *azDirs[] = {
|
|
||||||
0,
|
|
||||||
"/var/tmp",
|
|
||||||
"/usr/tmp",
|
|
||||||
"/tmp",
|
|
||||||
".",
|
|
||||||
};
|
|
||||||
static const unsigned char zChars[] =
|
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
"0123456789";
|
|
||||||
int i, j;
|
|
||||||
struct stat buf;
|
|
||||||
const char *zDir = ".";
|
|
||||||
azDirs[0] = sqlite3_temp_directory;
|
|
||||||
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
|
|
||||||
if( azDirs[i]==0 ) continue;
|
|
||||||
if( stat(azDirs[i], &buf) ) continue;
|
|
||||||
if( !S_ISDIR(buf.st_mode) ) continue;
|
|
||||||
if( access(azDirs[i], 07) ) continue;
|
|
||||||
zDir = azDirs[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
do{
|
|
||||||
sqlite3_snprintf(SQLITE_TEMPNAME_SIZE, zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
|
|
||||||
j = strlen(zBuf);
|
|
||||||
sqlite3Randomness(15, &zBuf[j]);
|
|
||||||
for(i=0; i<15; i++, j++){
|
|
||||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
|
||||||
}
|
|
||||||
zBuf[j] = 0;
|
|
||||||
}while( access(zBuf,0)==0 );
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check that a given pathname is a directory and is writable
|
** Check that a given pathname is a directory and is writable
|
||||||
**
|
**
|
||||||
@@ -1325,7 +1295,7 @@ static int unixCheckReservedLock(sqlite3_file *id){
|
|||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
|
|
||||||
assert( pFile );
|
assert( pFile );
|
||||||
sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */
|
enterMutex(); /* Because pFile->pLock is shared across threads */
|
||||||
|
|
||||||
/* Check if a thread in this process holds such a lock */
|
/* Check if a thread in this process holds such a lock */
|
||||||
if( pFile->pLock->locktype>SHARED_LOCK ){
|
if( pFile->pLock->locktype>SHARED_LOCK ){
|
||||||
@@ -1346,7 +1316,7 @@ static int unixCheckReservedLock(sqlite3_file *id){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
|
OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@@ -1428,7 +1398,7 @@ static int unixLock(sqlite3_file *id, int locktype){
|
|||||||
|
|
||||||
/* If there is already a lock of this type or more restrictive on the
|
/* If there is already a lock of this type or more restrictive on the
|
||||||
** OsFile, do nothing. Don't use the end_lock: exit path, as
|
** OsFile, do nothing. Don't use the end_lock: exit path, as
|
||||||
** sqlite3OsEnterMutex() hasn't been called yet.
|
** enterMutex() hasn't been called yet.
|
||||||
*/
|
*/
|
||||||
if( pFile->locktype>=locktype ){
|
if( pFile->locktype>=locktype ){
|
||||||
OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
|
OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
|
||||||
@@ -1444,13 +1414,13 @@ static int unixLock(sqlite3_file *id, int locktype){
|
|||||||
|
|
||||||
/* This mutex is needed because pFile->pLock is shared across threads
|
/* This mutex is needed because pFile->pLock is shared across threads
|
||||||
*/
|
*/
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
/* Make sure the current thread owns the pFile.
|
/* Make sure the current thread owns the pFile.
|
||||||
*/
|
*/
|
||||||
rc = transferOwnership(pFile);
|
rc = transferOwnership(pFile);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
pLock = pFile->pLock;
|
pLock = pFile->pLock;
|
||||||
@@ -1565,7 +1535,7 @@ static int unixLock(sqlite3_file *id, int locktype){
|
|||||||
}
|
}
|
||||||
|
|
||||||
end_lock:
|
end_lock:
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
|
OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
|
||||||
rc==SQLITE_OK ? "ok" : "failed");
|
rc==SQLITE_OK ? "ok" : "failed");
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1595,7 +1565,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
if( CHECK_THREADID(pFile) ){
|
if( CHECK_THREADID(pFile) ){
|
||||||
return SQLITE_MISUSE;
|
return SQLITE_MISUSE;
|
||||||
}
|
}
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
pLock = pFile->pLock;
|
pLock = pFile->pLock;
|
||||||
assert( pLock->cnt!=0 );
|
assert( pLock->cnt!=0 );
|
||||||
if( pFile->locktype>SHARED_LOCK ){
|
if( pFile->locktype>SHARED_LOCK ){
|
||||||
@@ -1656,7 +1626,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
pOpen->aPending = 0;
|
pOpen->aPending = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
pFile->locktype = locktype;
|
pFile->locktype = locktype;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1670,7 +1640,7 @@ static int unixClose(sqlite3_file *id){
|
|||||||
unixUnlock(id, NO_LOCK);
|
unixUnlock(id, NO_LOCK);
|
||||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||||
pFile->dirfd = -1;
|
pFile->dirfd = -1;
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
if( pFile->pOpen->nLock ){
|
if( pFile->pOpen->nLock ){
|
||||||
/* If there are outstanding locks, do not actually close the file just
|
/* If there are outstanding locks, do not actually close the file just
|
||||||
@@ -1695,11 +1665,11 @@ static int unixClose(sqlite3_file *id){
|
|||||||
releaseLockInfo(pFile->pLock);
|
releaseLockInfo(pFile->pLock);
|
||||||
releaseOpenCnt(pFile->pOpen);
|
releaseOpenCnt(pFile->pOpen);
|
||||||
|
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
pFile->isOpen = 0;
|
pFile->isOpen = 0;
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
sqlite3_free(id);
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1806,7 +1776,7 @@ static int afpUnixLock(OsFile *id, int locktype)
|
|||||||
locktypeName(locktype), locktypeName(pFile->locktype), getpid());
|
locktypeName(locktype), locktypeName(pFile->locktype), getpid());
|
||||||
/* If there is already a lock of this type or more restrictive on the
|
/* If there is already a lock of this type or more restrictive on the
|
||||||
** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
|
** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
|
||||||
** sqlite3OsEnterMutex() hasn't been called yet.
|
** enterMutex() hasn't been called yet.
|
||||||
*/
|
*/
|
||||||
if( pFile->locktype>=locktype ){
|
if( pFile->locktype>=locktype ){
|
||||||
OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
|
OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
|
||||||
@@ -1822,13 +1792,13 @@ static int afpUnixLock(OsFile *id, int locktype)
|
|||||||
|
|
||||||
/* This mutex is needed because pFile->pLock is shared across threads
|
/* This mutex is needed because pFile->pLock is shared across threads
|
||||||
*/
|
*/
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
/* Make sure the current thread owns the pFile.
|
/* Make sure the current thread owns the pFile.
|
||||||
*/
|
*/
|
||||||
rc = transferOwnership(pFile);
|
rc = transferOwnership(pFile);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1915,7 +1885,7 @@ static int afpUnixLock(OsFile *id, int locktype)
|
|||||||
}
|
}
|
||||||
|
|
||||||
afp_end_lock:
|
afp_end_lock:
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
|
OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
|
||||||
rc==SQLITE_OK ? "ok" : "failed");
|
rc==SQLITE_OK ? "ok" : "failed");
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1945,7 +1915,7 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
|
|||||||
if( CHECK_THREADID(pFile) ){
|
if( CHECK_THREADID(pFile) ){
|
||||||
return SQLITE_MISUSE;
|
return SQLITE_MISUSE;
|
||||||
}
|
}
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
if( pFile->locktype>SHARED_LOCK ){
|
if( pFile->locktype>SHARED_LOCK ){
|
||||||
if( locktype==SHARED_LOCK ){
|
if( locktype==SHARED_LOCK ){
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
@@ -1989,7 +1959,7 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
|
|||||||
}
|
}
|
||||||
if (rc == SQLITE_OK)
|
if (rc == SQLITE_OK)
|
||||||
pFile->locktype = locktype;
|
pFile->locktype = locktype;
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2103,10 +2073,10 @@ static int flockUnixClose(OsFile **pId) {
|
|||||||
|
|
||||||
if( id->dirfd>=0 ) close(id->dirfd);
|
if( id->dirfd>=0 ) close(id->dirfd);
|
||||||
id->dirfd = -1;
|
id->dirfd = -1;
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
close(id->h);
|
close(id->h);
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
id->isOpen = 0;
|
id->isOpen = 0;
|
||||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
@@ -2221,11 +2191,11 @@ static int dotlockUnixClose(OsFile **pId) {
|
|||||||
|
|
||||||
if( id->dirfd>=0 ) close(id->dirfd);
|
if( id->dirfd>=0 ) close(id->dirfd);
|
||||||
id->dirfd = -1;
|
id->dirfd = -1;
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
close(id->h);
|
close(id->h);
|
||||||
|
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
id->isOpen = 0;
|
id->isOpen = 0;
|
||||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
@@ -2263,11 +2233,11 @@ static int nolockUnixClose(OsFile **pId) {
|
|||||||
if( !id ) return SQLITE_OK;
|
if( !id ) return SQLITE_OK;
|
||||||
if( id->dirfd>=0 ) close(id->dirfd);
|
if( id->dirfd>=0 ) close(id->dirfd);
|
||||||
id->dirfd = -1;
|
id->dirfd = -1;
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
|
|
||||||
close(id->h);
|
close(id->h);
|
||||||
|
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
id->isOpen = 0;
|
id->isOpen = 0;
|
||||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
@@ -2278,56 +2248,6 @@ static int nolockUnixClose(OsFile **pId) {
|
|||||||
|
|
||||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||||
|
|
||||||
/*
|
|
||||||
** Turn a relative pathname into a full pathname. Return a pointer
|
|
||||||
** to the full pathname stored in space obtained from sqliteMalloc().
|
|
||||||
** The calling function is responsible for freeing this space once it
|
|
||||||
** is no longer needed.
|
|
||||||
*/
|
|
||||||
char *sqlite3UnixFullPathname(const char *zRelative){
|
|
||||||
char *zFull = 0;
|
|
||||||
if( zRelative[0]=='/' ){
|
|
||||||
sqlite3SetString(&zFull, zRelative, (char*)0);
|
|
||||||
}else{
|
|
||||||
char *zBuf = sqlite3_malloc(5000);
|
|
||||||
if( zBuf==0 ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
zBuf[0] = 0;
|
|
||||||
sqlite3SetString(&zFull, getcwd(zBuf, 5000), "/", zRelative,
|
|
||||||
(char*)0);
|
|
||||||
sqlite3_free(zBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
** Remove "/./" path elements and convert "/A/./" path elements
|
|
||||||
** to just "/".
|
|
||||||
*/
|
|
||||||
if( zFull ){
|
|
||||||
int i, j;
|
|
||||||
for(i=j=0; zFull[i]; i++){
|
|
||||||
if( zFull[i]=='/' ){
|
|
||||||
if( zFull[i+1]=='/' ) continue;
|
|
||||||
if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
|
|
||||||
i += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
|
|
||||||
while( j>0 && zFull[j-1]!='/' ){ j--; }
|
|
||||||
i += 3;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zFull[j++] = zFull[i];
|
|
||||||
}
|
|
||||||
zFull[j] = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return zFull;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the value of the fullsync flag in the given file descriptor.
|
** Change the value of the fullsync flag in the given file descriptor.
|
||||||
*/
|
*/
|
||||||
@@ -2510,9 +2430,9 @@ static int allocateUnixFile(
|
|||||||
memset(&f, 0, sizeof(f));
|
memset(&f, 0, sizeof(f));
|
||||||
lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
|
lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
|
||||||
if ( lockingStyle == posixLockingStyle ) {
|
if ( lockingStyle == posixLockingStyle ) {
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
rc = findLockInfo(h, &f.pLock, &f.pOpen);
|
rc = findLockInfo(h, &f.pLock, &f.pOpen);
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
if( rc ){
|
if( rc ){
|
||||||
close(h);
|
close(h);
|
||||||
unlink(zFilename);
|
unlink(zFilename);
|
||||||
@@ -2532,10 +2452,10 @@ static int allocateUnixFile(
|
|||||||
pNew = sqlite3_malloc( sizeof(unixFile) );
|
pNew = sqlite3_malloc( sizeof(unixFile) );
|
||||||
if( pNew==0 ){
|
if( pNew==0 ){
|
||||||
close(h);
|
close(h);
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
releaseLockInfo(f.pLock);
|
releaseLockInfo(f.pLock);
|
||||||
releaseOpenCnt(f.pOpen);
|
releaseOpenCnt(f.pOpen);
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
*pId = 0;
|
*pId = 0;
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
@@ -2590,51 +2510,35 @@ static int allocateUnixFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* SQLITE_ENABLE_LOCKING_STYLE */
|
#else /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||||
static int allocateUnixFile(
|
static int fillInUnixFile(
|
||||||
int h, /* Open file descriptor on file being opened */
|
int h, /* Open file descriptor on file being opened */
|
||||||
sqlite3_file **pId, /* Write the resul unixFile structure here */
|
sqlite3_file *pId, /* Write to the unixFile structure here */
|
||||||
const char *zFilename, /* Name of the file being opened */
|
const char *zFilename /* Name of the file being opened */
|
||||||
int delFlag /* If true, delete the file on or before closing */
|
|
||||||
){
|
){
|
||||||
unixFile *pNew;
|
unixFile *pNew = (unixFile *)pId;
|
||||||
unixFile f;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
|
fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
memset(&f, 0, sizeof(f));
|
|
||||||
sqlite3OsEnterMutex();
|
enterMutex();
|
||||||
rc = findLockInfo(h, &f.pLock, &f.pOpen);
|
rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
|
||||||
sqlite3OsLeaveMutex();
|
leaveMutex();
|
||||||
if( delFlag ){
|
|
||||||
unlink(zFilename);
|
|
||||||
}
|
|
||||||
if( rc ){
|
if( rc ){
|
||||||
close(h);
|
close(h);
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
||||||
f.dirfd = -1;
|
pNew->dirfd = -1;
|
||||||
f.h = h;
|
pNew->h = h;
|
||||||
SET_THREADID(&f);
|
SET_THREADID(pNew);
|
||||||
pNew = sqlite3_malloc( sizeof(unixFile) );
|
|
||||||
if( pNew==0 ){
|
|
||||||
close(h);
|
|
||||||
sqlite3OsEnterMutex();
|
|
||||||
releaseLockInfo(f.pLock);
|
|
||||||
releaseOpenCnt(f.pOpen);
|
|
||||||
sqlite3OsLeaveMutex();
|
|
||||||
*pId = 0;
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}else{
|
|
||||||
*pNew = f;
|
|
||||||
pNew->pMethod = &sqlite3UnixIoMethod;
|
pNew->pMethod = &sqlite3UnixIoMethod;
|
||||||
*pId = (sqlite3_file*)pNew;
|
|
||||||
OpenCounter(+1);
|
OpenCounter(+1);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||||
|
|
||||||
#endif /* SQLITE_OMIT_DISKIO */
|
#endif /* SQLITE_OMIT_DISKIO */
|
||||||
@@ -2643,6 +2547,199 @@ static int allocateUnixFile(
|
|||||||
** with other miscellanous aspects of the operating system interface
|
** with other miscellanous aspects of the operating system interface
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Previously, the SQLite OS layer used three functions in place of this
|
||||||
|
** one:
|
||||||
|
**
|
||||||
|
** sqlite3OsOpenReadWrite();
|
||||||
|
** sqlite3OsOpenReadOnly();
|
||||||
|
** sqlite3OsOpenExclusive();
|
||||||
|
**
|
||||||
|
** These calls correspond to the following combinations of flags:
|
||||||
|
**
|
||||||
|
** ReadWrite() -> (READWRITE | CREATE)
|
||||||
|
** ReadOnly() -> (READONLY)
|
||||||
|
** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
|
||||||
|
**
|
||||||
|
** The old OpenExclusive() accepted a boolean argument - "delFlag". If
|
||||||
|
** true, the file was configured to be automatically deleted when the
|
||||||
|
** file handle closed. To achieve the same effect using this new
|
||||||
|
** interface, add the DELETEONCLOSE flag to those specified above for
|
||||||
|
** OpenExclusive().
|
||||||
|
*/
|
||||||
|
static int unixOpen(
|
||||||
|
void *pNotUsed,
|
||||||
|
const char *zPath,
|
||||||
|
sqlite3_file *pFile,
|
||||||
|
int flags,
|
||||||
|
int *pOutFlags
|
||||||
|
){
|
||||||
|
int fd = 0;
|
||||||
|
int oflags = 0;
|
||||||
|
|
||||||
|
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
|
||||||
|
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
|
||||||
|
int isCreate = (flags & SQLITE_OPEN_CREATE);
|
||||||
|
int isReadonly = (flags & SQLITE_OPEN_READONLY);
|
||||||
|
int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
|
||||||
|
|
||||||
|
/* Exactly one of the READWRITE and READONLY flags must be set */
|
||||||
|
assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
|
||||||
|
|
||||||
|
/* If isCreate is true, then the file must be opened for read/write access. */
|
||||||
|
assert(isCreate==0 || isReadWrite);
|
||||||
|
|
||||||
|
/* If isExclusive is true, then isCreate must also be true */
|
||||||
|
assert(isExclusive==0 || isCreate);
|
||||||
|
|
||||||
|
if( isReadonly ) oflags |= O_RDONLY;
|
||||||
|
if( isReadWrite ) oflags |= O_RDWR;
|
||||||
|
if( isCreate ) oflags |= O_CREAT;
|
||||||
|
if( isExclusive ) oflags |= (O_EXCL|O_NOFOLLOW);
|
||||||
|
oflags |= (O_LARGEFILE|O_BINARY);
|
||||||
|
|
||||||
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
|
fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||||
|
if( fd<0 && isReadWrite && !isExclusive ){
|
||||||
|
/* Failed to open the file for read/write access. Try read-only. */
|
||||||
|
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||||
|
flags |= SQLITE_OPEN_READONLY;
|
||||||
|
return unixOpen(pNotUsed, zPath, pFile, flags, pOutFlags);
|
||||||
|
}
|
||||||
|
if( fd<0 ){
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
if( isDelete ){
|
||||||
|
unlink(zPath);
|
||||||
|
}
|
||||||
|
if( pOutFlags ){
|
||||||
|
*pOutFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(fd!=0);
|
||||||
|
return fillInUnixFile(fd, pFile, zPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete the file at zPath.
|
||||||
|
*/
|
||||||
|
static int unixDelete(void *pNotUsed, const char *zPath){
|
||||||
|
SimulateIOError(return SQLITE_IOERR_DELETE);
|
||||||
|
unlink(zPath);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int unixAccess(void *pNotUsed, const char *zPath, int flags){
|
||||||
|
int amode;
|
||||||
|
switch( flags ){
|
||||||
|
case SQLITE_ACCESS_EXISTS:
|
||||||
|
amode = F_OK;
|
||||||
|
break;
|
||||||
|
case SQLITE_ACCESS_READWRITE:
|
||||||
|
amode = W_OK|R_OK;
|
||||||
|
break;
|
||||||
|
case SQLITE_ACCESS_READONLY:
|
||||||
|
amode = R_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(!"Invalid flags argument");
|
||||||
|
}
|
||||||
|
return (access(zPath, amode)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||||
|
** hold at least MAX_PATHNAME characters.
|
||||||
|
*/
|
||||||
|
static int unixGetTempName(void *pNotUsed, char *zBuf){
|
||||||
|
static const char *azDirs[] = {
|
||||||
|
0,
|
||||||
|
"/var/tmp",
|
||||||
|
"/usr/tmp",
|
||||||
|
"/tmp",
|
||||||
|
".",
|
||||||
|
};
|
||||||
|
static const unsigned char zChars[] =
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"0123456789";
|
||||||
|
int i, j;
|
||||||
|
struct stat buf;
|
||||||
|
const char *zDir = ".";
|
||||||
|
azDirs[0] = sqlite3_temp_directory;
|
||||||
|
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
|
||||||
|
if( azDirs[i]==0 ) continue;
|
||||||
|
if( stat(azDirs[i], &buf) ) continue;
|
||||||
|
if( !S_ISDIR(buf.st_mode) ) continue;
|
||||||
|
if( access(azDirs[i], 07) ) continue;
|
||||||
|
zDir = azDirs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
do{
|
||||||
|
sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
|
||||||
|
j = strlen(zBuf);
|
||||||
|
sqlite3Randomness(15, &zBuf[j]);
|
||||||
|
for(i=0; i<15; i++, j++){
|
||||||
|
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||||
|
}
|
||||||
|
zBuf[j] = 0;
|
||||||
|
}while( access(zBuf,0)==0 );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Turn a relative pathname into a full pathname. The relative path
|
||||||
|
** is stored as a nul-terminated string in the buffer pointed to by
|
||||||
|
** zPath.
|
||||||
|
**
|
||||||
|
** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes
|
||||||
|
** (in this case, MAX_PATHNAME bytes). The full-path is written to
|
||||||
|
** this buffer before returning.
|
||||||
|
*/
|
||||||
|
static int unixFullPathname(void *pNotUsed, const char *zPath, char *zOut){
|
||||||
|
zOut[MAX_PATHNAME-1] = '\0';
|
||||||
|
if( zPath[0]=='/' ){
|
||||||
|
strncpy(zOut, zPath, MAX_PATHNAME-1);
|
||||||
|
}else{
|
||||||
|
int nCwd;
|
||||||
|
if( getcwd(zOut, MAX_PATHNAME-1)==0 ){
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
nCwd = strlen(zOut);
|
||||||
|
zOut[nCwd] = '/';
|
||||||
|
strncpy(&zOut[nCwd+1], zPath, MAX_PATHNAME-1-nCwd-1);
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
** Remove "/./" path elements and convert "/A/./" path elements
|
||||||
|
** to just "/".
|
||||||
|
*/
|
||||||
|
if( zFull ){
|
||||||
|
int i, j;
|
||||||
|
for(i=j=0; zFull[i]; i++){
|
||||||
|
if( zFull[i]=='/' ){
|
||||||
|
if( zFull[i+1]=='/' ) continue;
|
||||||
|
if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
|
||||||
|
while( j>0 && zFull[j-1]!='/' ){ j--; }
|
||||||
|
i += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zFull[j++] = zFull[i];
|
||||||
|
}
|
||||||
|
zFull[j] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||||
/*
|
/*
|
||||||
@@ -2650,23 +2747,46 @@ static int allocateUnixFile(
|
|||||||
** within the shared library, and closing the shared library.
|
** within the shared library, and closing the shared library.
|
||||||
*/
|
*/
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
void *sqlite3UnixDlopen(const char *zFilename){
|
static void *unixDlOpen(void *pNotUsed, const char *zFilename){
|
||||||
return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
|
return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
|
||||||
}
|
}
|
||||||
void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){
|
static void unixDlError(void *pNotUsed, int nBuf, char *zBufOut){
|
||||||
|
char *zErr;
|
||||||
|
enterMutex();
|
||||||
|
zErr = dlerror();
|
||||||
|
if( zErr ){
|
||||||
|
strncpy(zBufOut, zErr, nBuf-1);
|
||||||
|
zBufOut[nBuf-1] = '\0';
|
||||||
|
}else if(nBuf>0) {
|
||||||
|
zBufOut[0] = '\0';
|
||||||
|
}
|
||||||
|
leaveMutex();
|
||||||
|
}
|
||||||
|
void *unixDlSym(void *pHandle, const char *zSymbol){
|
||||||
return dlsym(pHandle, zSymbol);
|
return dlsym(pHandle, zSymbol);
|
||||||
}
|
}
|
||||||
int sqlite3UnixDlclose(void *pHandle){
|
void unixDlClose(void *pHandle){
|
||||||
return dlclose(pHandle);
|
dlclose(pHandle);
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
|
||||||
|
#define unixDlOpen 0
|
||||||
|
#define unixDlError 0
|
||||||
|
#define unixDlSym 0
|
||||||
|
#define unixDlClose 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Both arguments are integers. This macro returns the lowest of the
|
||||||
|
** two arguments.
|
||||||
|
*/
|
||||||
|
#define MIN(x,y) ((x)>(y)?(y):(x))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Get information to seed the random number generator. The seed
|
** Get information to seed the random number generator. The seed
|
||||||
** is written into the buffer zBuf[256]. The calling function must
|
** is written into the buffer zBuf[256]. The calling function must
|
||||||
** supply a sufficiently large buffer.
|
** supply a sufficiently large buffer.
|
||||||
*/
|
*/
|
||||||
int sqlite3UnixRandomSeed(char *zBuf){
|
static int unixRandomness(void *pNotUsed, int nBuf, char *zBuf){
|
||||||
/* We have to initialize zBuf to prevent valgrind from reporting
|
/* We have to initialize zBuf to prevent valgrind from reporting
|
||||||
** errors. The reports issued by valgrind are incorrect - we would
|
** errors. The reports issued by valgrind are incorrect - we would
|
||||||
** prefer that the randomness be increased by making use of the
|
** prefer that the randomness be increased by making use of the
|
||||||
@@ -2679,7 +2799,7 @@ int sqlite3UnixRandomSeed(char *zBuf){
|
|||||||
** that we always use the same random number sequence. This makes the
|
** that we always use the same random number sequence. This makes the
|
||||||
** tests repeatable.
|
** tests repeatable.
|
||||||
*/
|
*/
|
||||||
memset(zBuf, 0, 256);
|
memset(zBuf, 0, nBuf);
|
||||||
#if !defined(SQLITE_TEST)
|
#if !defined(SQLITE_TEST)
|
||||||
{
|
{
|
||||||
int pid, fd;
|
int pid, fd;
|
||||||
@@ -2687,11 +2807,13 @@ int sqlite3UnixRandomSeed(char *zBuf){
|
|||||||
if( fd<0 ){
|
if( fd<0 ){
|
||||||
time_t t;
|
time_t t;
|
||||||
time(&t);
|
time(&t);
|
||||||
memcpy(zBuf, &t, sizeof(t));
|
memcpy(zBuf, &t, MIN(nBuf, sizeof(t)));
|
||||||
|
if( (nBuf-sizeof(t))>0 ){
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
|
memcpy(&zBuf[sizeof(t)], &pid, MIN(nBuf-sizeof(t), sizeof(pid)));
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
read(fd, zBuf, 256);
|
read(fd, zBuf, nBuf);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2699,120 +2821,19 @@ int sqlite3UnixRandomSeed(char *zBuf){
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Sleep for a little while. Return the amount of time slept.
|
** Sleep for a little while. Return the amount of time slept.
|
||||||
** The argument is the number of milliseconds we want to sleep.
|
** The argument is the number of microseconds we want to sleep.
|
||||||
*/
|
*/
|
||||||
int sqlite3UnixSleep(int ms){
|
static int unixSleep(void *pNotUsed, int microseconds){
|
||||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||||
usleep(ms*1000);
|
usleep(microseconds);
|
||||||
return ms;
|
return microseconds;
|
||||||
#else
|
#else
|
||||||
sleep((ms+999)/1000);
|
int seconds = (microseconds+999999)/1000000;
|
||||||
return 1000*((ms+999)/1000);
|
sleep(seconds);
|
||||||
#endif
|
return seconds;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Static variables used for thread synchronization.
|
|
||||||
**
|
|
||||||
** inMutex the nesting depth of the recursive mutex. The thread
|
|
||||||
** holding mutexMain can read this variable at any time.
|
|
||||||
** But is must hold mutexAux to change this variable. Other
|
|
||||||
** threads must hold mutexAux to read the variable and can
|
|
||||||
** never write.
|
|
||||||
**
|
|
||||||
** mutexOwner The thread id of the thread holding mutexMain. Same
|
|
||||||
** access rules as for inMutex.
|
|
||||||
**
|
|
||||||
** mutexOwnerValid True if the value in mutexOwner is valid. The same
|
|
||||||
** access rules apply as for inMutex.
|
|
||||||
**
|
|
||||||
** mutexMain The main mutex. Hold this mutex in order to get exclusive
|
|
||||||
** access to SQLite data structures.
|
|
||||||
**
|
|
||||||
** mutexAux An auxiliary mutex needed to access variables defined above.
|
|
||||||
**
|
|
||||||
** Mutexes are always acquired in this order: mutexMain mutexAux. It
|
|
||||||
** is not necessary to acquire mutexMain in order to get mutexAux - just
|
|
||||||
** do not attempt to acquire them in the reverse order: mutexAux mutexMain.
|
|
||||||
** Either get the mutexes with mutexMain first or get mutexAux only.
|
|
||||||
**
|
|
||||||
** When running on a platform where the three variables inMutex, mutexOwner,
|
|
||||||
** and mutexOwnerValid can be set atomically, the mutexAux is not required.
|
|
||||||
** On many systems, all three are 32-bit integers and writing to a 32-bit
|
|
||||||
** integer is atomic. I think. But there are no guarantees. So it seems
|
|
||||||
** safer to protect them using mutexAux.
|
|
||||||
*/
|
|
||||||
static int inMutex = 0;
|
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
|
||||||
static pthread_t mutexOwner; /* Thread holding mutexMain */
|
|
||||||
static int mutexOwnerValid = 0; /* True if mutexOwner is valid */
|
|
||||||
static pthread_mutex_t mutexMain = PTHREAD_MUTEX_INITIALIZER; /* The mutex */
|
|
||||||
static pthread_mutex_t mutexAux = PTHREAD_MUTEX_INITIALIZER; /* Aux mutex */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The following pair of routine implement mutual exclusion for
|
|
||||||
** multi-threaded processes. Only a single thread is allowed to
|
|
||||||
** executed code that is surrounded by EnterMutex() and LeaveMutex().
|
|
||||||
**
|
|
||||||
** SQLite uses only a single Mutex. There is not much critical
|
|
||||||
** code and what little there is executes quickly and without blocking.
|
|
||||||
**
|
|
||||||
** As of version 3.3.2, this mutex must be recursive.
|
|
||||||
*/
|
|
||||||
void sqlite3UnixEnterMutex(){
|
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
|
||||||
pthread_mutex_lock(&mutexAux);
|
|
||||||
if( !mutexOwnerValid || !pthread_equal(mutexOwner, pthread_self()) ){
|
|
||||||
pthread_mutex_unlock(&mutexAux);
|
|
||||||
pthread_mutex_lock(&mutexMain);
|
|
||||||
assert( inMutex==0 );
|
|
||||||
assert( !mutexOwnerValid );
|
|
||||||
pthread_mutex_lock(&mutexAux);
|
|
||||||
mutexOwner = pthread_self();
|
|
||||||
mutexOwnerValid = 1;
|
|
||||||
}
|
|
||||||
inMutex++;
|
|
||||||
pthread_mutex_unlock(&mutexAux);
|
|
||||||
#else
|
|
||||||
inMutex++;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
void sqlite3UnixLeaveMutex(){
|
|
||||||
assert( inMutex>0 );
|
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
|
||||||
pthread_mutex_lock(&mutexAux);
|
|
||||||
inMutex--;
|
|
||||||
assert( pthread_equal(mutexOwner, pthread_self()) );
|
|
||||||
if( inMutex==0 ){
|
|
||||||
assert( mutexOwnerValid );
|
|
||||||
mutexOwnerValid = 0;
|
|
||||||
pthread_mutex_unlock(&mutexMain);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&mutexAux);
|
|
||||||
#else
|
|
||||||
inMutex--;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Return TRUE if the mutex is currently held.
|
|
||||||
**
|
|
||||||
** If the thisThrd parameter is true, return true only if the
|
|
||||||
** calling thread holds the mutex. If the parameter is false, return
|
|
||||||
** true if any thread holds the mutex.
|
|
||||||
*/
|
|
||||||
int sqlite3UnixInMutex(int thisThrd){
|
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
|
||||||
int rc;
|
|
||||||
pthread_mutex_lock(&mutexAux);
|
|
||||||
rc = inMutex>0 && (thisThrd==0 || pthread_equal(mutexOwner,pthread_self()));
|
|
||||||
pthread_mutex_unlock(&mutexAux);
|
|
||||||
return rc;
|
|
||||||
#else
|
|
||||||
return inMutex>0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2829,7 +2850,7 @@ int sqlite3_current_time = 0;
|
|||||||
** current time and date as a Julian Day number into *prNow and
|
** current time and date as a Julian Day number into *prNow and
|
||||||
** return 0. Return 1 if the time and date cannot be found.
|
** return 0. Return 1 if the time and date cannot be found.
|
||||||
*/
|
*/
|
||||||
int sqlite3UnixCurrentTime(double *prNow){
|
static int unixCurrentTime(void *pNotUsed, double *prNow){
|
||||||
#ifdef NO_GETTOD
|
#ifdef NO_GETTOD
|
||||||
time_t t;
|
time_t t;
|
||||||
time(&t);
|
time(&t);
|
||||||
@@ -2847,4 +2868,30 @@ int sqlite3UnixCurrentTime(double *prNow){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sqlite3_vfs sqlite3DefaultVfs = {
|
||||||
|
1, /* iVersion */
|
||||||
|
sizeof(unixFile), /* szOsFile */
|
||||||
|
MAX_PATHNAME, /* mxPathname */
|
||||||
|
0, /* nRef */
|
||||||
|
0, /* vfsMutex */
|
||||||
|
0, /* pNext */
|
||||||
|
0, /* pPrev */
|
||||||
|
"unix", /* zName */
|
||||||
|
0, /* pAppData */
|
||||||
|
|
||||||
|
unixOpen, /* xOpen */
|
||||||
|
unixDelete, /* xDelete */
|
||||||
|
unixAccess, /* xAccess */
|
||||||
|
unixGetTempName, /* xGetTempName */
|
||||||
|
unixFullPathname, /* xFullPathname */
|
||||||
|
unixDlOpen, /* xDlOpen */
|
||||||
|
unixDlError, /* xDlError */
|
||||||
|
unixDlSym, /* xDlSym */
|
||||||
|
unixDlClose, /* xDlClose */
|
||||||
|
unixRandomness, /* xRandomness */
|
||||||
|
unixSleep, /* xSleep */
|
||||||
|
unixCurrentTime /* xCurrentTime */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* OS_UNIX */
|
#endif /* OS_UNIX */
|
||||||
|
199
src/pager.c
199
src/pager.c
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.358 2007/08/16 10:09:03 danielk1977 Exp $
|
** @(#) $Id: pager.c,v 1.359 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -297,6 +297,7 @@ struct PgHistory {
|
|||||||
** APIs, they may still be used successfully.
|
** APIs, they may still be used successfully.
|
||||||
*/
|
*/
|
||||||
struct Pager {
|
struct Pager {
|
||||||
|
sqlite3_vfs *pVfs; /* OS functions to use for IO */
|
||||||
u8 journalOpen; /* True if journal file descriptors is valid */
|
u8 journalOpen; /* True if journal file descriptors is valid */
|
||||||
u8 journalStarted; /* True if header of journal is synced */
|
u8 journalStarted; /* True if header of journal is synced */
|
||||||
u8 useJournal; /* Use a rollback journal on this file */
|
u8 useJournal; /* Use a rollback journal on this file */
|
||||||
@@ -1011,7 +1012,7 @@ static int pager_end_transaction(Pager *pPager){
|
|||||||
}
|
}
|
||||||
sqlite3PagerStmtCommit(pPager);
|
sqlite3PagerStmtCommit(pPager);
|
||||||
if( pPager->stmtOpen && !pPager->exclusiveMode ){
|
if( pPager->stmtOpen && !pPager->exclusiveMode ){
|
||||||
sqlite3OsClose(&pPager->stfd);
|
sqlite3OsClose(pPager->stfd);
|
||||||
pPager->stmtOpen = 0;
|
pPager->stmtOpen = 0;
|
||||||
}
|
}
|
||||||
if( pPager->journalOpen ){
|
if( pPager->journalOpen ){
|
||||||
@@ -1020,10 +1021,10 @@ static int pager_end_transaction(Pager *pPager){
|
|||||||
pPager->journalOff = 0;
|
pPager->journalOff = 0;
|
||||||
pPager->journalStarted = 0;
|
pPager->journalStarted = 0;
|
||||||
}else{
|
}else{
|
||||||
sqlite3OsClose(&pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
pPager->journalOpen = 0;
|
pPager->journalOpen = 0;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3OsDelete(pPager->zJournal);
|
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3_free( pPager->aInJournal );
|
sqlite3_free( pPager->aInJournal );
|
||||||
@@ -1225,21 +1226,29 @@ static int pager_playback_one_page(
|
|||||||
** children. If all children are either missing or do not refer to
|
** children. If all children are either missing or do not refer to
|
||||||
** a different master journal, then this master journal can be deleted.
|
** a different master journal, then this master journal can be deleted.
|
||||||
*/
|
*/
|
||||||
static int pager_delmaster(const char *zMaster){
|
static int pager_delmaster(Pager *pPager, const char *zMaster){
|
||||||
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
int rc;
|
int rc;
|
||||||
int master_open = 0;
|
int master_open = 0;
|
||||||
sqlite3_file *master = 0;
|
sqlite3_file *pMaster;
|
||||||
|
sqlite3_file *pJournal;
|
||||||
char *zMasterJournal = 0; /* Contents of master journal file */
|
char *zMasterJournal = 0; /* Contents of master journal file */
|
||||||
i64 nMasterJournal; /* Size of master journal file */
|
i64 nMasterJournal; /* Size of master journal file */
|
||||||
|
|
||||||
/* Open the master journal file exclusively in case some other process
|
/* Open the master journal file exclusively in case some other process
|
||||||
** is running this routine also. Not that it makes too much difference.
|
** is running this routine also. Not that it makes too much difference.
|
||||||
*/
|
*/
|
||||||
rc = sqlite3OsOpenReadOnly(zMaster, &master);
|
pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2);
|
||||||
assert( rc!=SQLITE_OK || master );
|
if( !pMaster ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
|
||||||
|
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, SQLITE_OPEN_READONLY, 0);
|
||||||
|
}
|
||||||
if( rc!=SQLITE_OK ) goto delmaster_out;
|
if( rc!=SQLITE_OK ) goto delmaster_out;
|
||||||
master_open = 1;
|
master_open = 1;
|
||||||
rc = sqlite3OsFileSize(master, &nMasterJournal);
|
|
||||||
|
rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
|
||||||
if( rc!=SQLITE_OK ) goto delmaster_out;
|
if( rc!=SQLITE_OK ) goto delmaster_out;
|
||||||
|
|
||||||
if( nMasterJournal>0 ){
|
if( nMasterJournal>0 ){
|
||||||
@@ -1254,27 +1263,25 @@ static int pager_delmaster(const char *zMaster){
|
|||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto delmaster_out;
|
goto delmaster_out;
|
||||||
}
|
}
|
||||||
rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal, 0);
|
rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
|
||||||
if( rc!=SQLITE_OK ) goto delmaster_out;
|
if( rc!=SQLITE_OK ) goto delmaster_out;
|
||||||
|
|
||||||
zJournal = zMasterJournal;
|
zJournal = zMasterJournal;
|
||||||
while( (zJournal-zMasterJournal)<nMasterJournal ){
|
while( (zJournal-zMasterJournal)<nMasterJournal ){
|
||||||
if( sqlite3OsFileExists(zJournal) ){
|
if( sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS) ){
|
||||||
/* One of the journals pointed to by the master journal exists.
|
/* One of the journals pointed to by the master journal exists.
|
||||||
** Open it and check if it points at the master journal. If
|
** Open it and check if it points at the master journal. If
|
||||||
** so, return without deleting the master journal file.
|
** so, return without deleting the master journal file.
|
||||||
*/
|
*/
|
||||||
sqlite3_file *journal = 0;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
rc = sqlite3OsOpenReadOnly(zJournal, &journal);
|
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, SQLITE_OPEN_READONLY, 0);
|
||||||
assert( rc!=SQLITE_OK || journal );
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto delmaster_out;
|
goto delmaster_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = readMasterJournal(journal, &zMasterPtr);
|
rc = readMasterJournal(pJournal, &zMasterPtr);
|
||||||
sqlite3OsClose(&journal);
|
sqlite3OsClose(pJournal);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto delmaster_out;
|
goto delmaster_out;
|
||||||
}
|
}
|
||||||
@@ -1290,15 +1297,16 @@ static int pager_delmaster(const char *zMaster){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3OsDelete(zMaster);
|
rc = sqlite3OsDelete(pVfs, zMaster);
|
||||||
|
|
||||||
delmaster_out:
|
delmaster_out:
|
||||||
if( zMasterJournal ){
|
if( zMasterJournal ){
|
||||||
sqlite3_free(zMasterJournal);
|
sqlite3_free(zMasterJournal);
|
||||||
}
|
}
|
||||||
if( master_open ){
|
if( master_open ){
|
||||||
sqlite3OsClose(&master);
|
sqlite3OsClose(pMaster);
|
||||||
}
|
}
|
||||||
|
sqlite3_free(pMaster);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,6 +1396,7 @@ static void setSectorSize(Pager *pPager){
|
|||||||
** and an error code is returned.
|
** and an error code is returned.
|
||||||
*/
|
*/
|
||||||
static int pager_playback(Pager *pPager, int isHot){
|
static int pager_playback(Pager *pPager, int isHot){
|
||||||
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
i64 szJ; /* Size of the journal file in bytes */
|
i64 szJ; /* Size of the journal file in bytes */
|
||||||
u32 nRec; /* Number of Records in the journal */
|
u32 nRec; /* Number of Records in the journal */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
@@ -1411,7 +1420,9 @@ static int pager_playback(Pager *pPager, int isHot){
|
|||||||
*/
|
*/
|
||||||
rc = readMasterJournal(pPager->jfd, &zMaster);
|
rc = readMasterJournal(pPager->jfd, &zMaster);
|
||||||
assert( rc!=SQLITE_DONE );
|
assert( rc!=SQLITE_DONE );
|
||||||
if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
|
if( rc!=SQLITE_OK
|
||||||
|
|| (zMaster && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS))
|
||||||
|
){
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
zMaster = 0;
|
zMaster = 0;
|
||||||
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
|
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
|
||||||
@@ -1496,7 +1507,7 @@ end_playback:
|
|||||||
** see if it is possible to delete the master journal.
|
** see if it is possible to delete the master journal.
|
||||||
*/
|
*/
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = pager_delmaster(zMaster);
|
rc = pager_delmaster(pPager, zMaster);
|
||||||
}
|
}
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
}
|
}
|
||||||
@@ -1681,20 +1692,36 @@ int sqlite3_opentemp_count = 0;
|
|||||||
** The OS will automatically delete the temporary file when it is
|
** The OS will automatically delete the temporary file when it is
|
||||||
** closed.
|
** closed.
|
||||||
*/
|
*/
|
||||||
static int sqlite3PagerOpentemp(sqlite3_file **pFd){
|
static int sqlite3PagerOpentemp(
|
||||||
|
sqlite3_vfs *pVfs,
|
||||||
|
sqlite3_file *pFile,
|
||||||
|
char *zNameOut
|
||||||
|
){
|
||||||
int cnt = 8;
|
int cnt = 8;
|
||||||
int rc;
|
int rc;
|
||||||
char zFile[SQLITE_TEMPNAME_SIZE];
|
int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_EXCLUSIVE);
|
||||||
|
|
||||||
|
char *zFree = 0;
|
||||||
|
if( zNameOut==0 ){
|
||||||
|
zFree = (char *)sqlite3_malloc(pVfs->mxPathname);
|
||||||
|
if( !zFree ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
zNameOut = zFree;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
sqlite3_opentemp_count++; /* Used for testing and analysis only */
|
sqlite3_opentemp_count++; /* Used for testing and analysis only */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do{
|
do{
|
||||||
cnt--;
|
cnt--;
|
||||||
sqlite3OsTempFileName(zFile);
|
sqlite3OsGetTempName(pVfs, zNameOut);
|
||||||
rc = sqlite3OsOpenExclusive(zFile, pFd, 1);
|
rc = sqlite3OsOpen(pVfs, zNameOut, pFile, flags, 0);
|
||||||
assert( rc!=SQLITE_OK || *pFd );
|
assert( rc!=SQLITE_OK || pFile->pMethods );
|
||||||
}while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
|
}while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
|
||||||
|
|
||||||
|
sqlite3_free(zFree);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1713,15 +1740,15 @@ static int sqlite3PagerOpentemp(sqlite3_file **pFd){
|
|||||||
** in-memory database.
|
** in-memory database.
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerOpen(
|
int sqlite3PagerOpen(
|
||||||
|
sqlite3_vfs *pVfs,
|
||||||
Pager **ppPager, /* Return the Pager structure here */
|
Pager **ppPager, /* Return the Pager structure here */
|
||||||
const char *zFilename, /* Name of the database file to open */
|
const char *zFilename, /* Name of the database file to open */
|
||||||
int nExtra, /* Extra bytes append to each in-memory page */
|
int nExtra, /* Extra bytes append to each in-memory page */
|
||||||
int flags /* flags controlling this file */
|
int flags /* flags controlling this file */
|
||||||
){
|
){
|
||||||
|
u8 *pPtr;
|
||||||
Pager *pPager = 0;
|
Pager *pPager = 0;
|
||||||
char *zFullPathname = 0;
|
char *zFullPathname = 0;
|
||||||
int nameLen; /* Compiler is wrong. This is always initialized before use */
|
|
||||||
sqlite3_file *fd = 0;
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int i;
|
int i;
|
||||||
int tempFile = 0;
|
int tempFile = 0;
|
||||||
@@ -1729,7 +1756,7 @@ int sqlite3PagerOpen(
|
|||||||
int readOnly = 0;
|
int readOnly = 0;
|
||||||
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
|
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
|
||||||
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
|
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
|
||||||
char zTemp[SQLITE_TEMPNAME_SIZE];
|
|
||||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||||
/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to
|
/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to
|
||||||
** malloc() must have already been made by this thread before it gets
|
** malloc() must have already been made by this thread before it gets
|
||||||
@@ -1750,6 +1777,24 @@ int sqlite3PagerOpen(
|
|||||||
*/
|
*/
|
||||||
*ppPager = 0;
|
*ppPager = 0;
|
||||||
|
|
||||||
|
/* Allocate memory for the pager structure */
|
||||||
|
pPager = sqlite3MallocZero(
|
||||||
|
sizeof(*pPager) + /* Pager structure */
|
||||||
|
pVfs->szOsFile * 3 + /* The db, journal and stmt journal files */
|
||||||
|
pVfs->mxPathname * 3 + 30 /* zFilename, zDirectory, zJournal */
|
||||||
|
);
|
||||||
|
if( !pPager ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pPtr = (u8 *)&pPager[1];
|
||||||
|
pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
|
||||||
|
pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1];
|
||||||
|
pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2];
|
||||||
|
pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*3];
|
||||||
|
pPager->zDirectory = &pPager->zFilename[pVfs->mxPathname];
|
||||||
|
pPager->zJournal = &pPager->zDirectory[pVfs->mxPathname];
|
||||||
|
pPager->pVfs = pVfs;
|
||||||
|
|
||||||
/* Open the pager file and set zFullPathname to point at malloc()ed
|
/* Open the pager file and set zFullPathname to point at malloc()ed
|
||||||
** memory containing the complete filename (i.e. including the directory).
|
** memory containing the complete filename (i.e. including the directory).
|
||||||
*/
|
*/
|
||||||
@@ -1757,65 +1802,56 @@ int sqlite3PagerOpen(
|
|||||||
#ifndef SQLITE_OMIT_MEMORYDB
|
#ifndef SQLITE_OMIT_MEMORYDB
|
||||||
if( strcmp(zFilename,":memory:")==0 ){
|
if( strcmp(zFilename,":memory:")==0 ){
|
||||||
memDb = 1;
|
memDb = 1;
|
||||||
zFullPathname = sqlite3StrDup("");
|
pPager->zFilename[0] = '\0';
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
zFullPathname = sqlite3OsFullPathname(zFilename);
|
rc = sqlite3OsFullPathname(pVfs, zFilename, pPager->zFilename);
|
||||||
if( zFullPathname ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
|
if( strlen(pPager->zFilename)>(pVfs->mxPathname - strlen("-journal")) ){
|
||||||
assert( rc!=SQLITE_OK || fd );
|
rc = SQLITE_CANTOPEN;
|
||||||
|
}else{
|
||||||
|
int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||||
|
int fout = 0;
|
||||||
|
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, flag, &fout);
|
||||||
|
readOnly = (fout&SQLITE_OPEN_READONLY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3PagerOpentemp(&fd);
|
rc = sqlite3PagerOpentemp(pVfs, pPager->fd, pPager->zFilename);
|
||||||
sqlite3OsTempFileName(zTemp);
|
|
||||||
zFilename = zTemp;
|
|
||||||
zFullPathname = sqlite3OsFullPathname(zFilename);
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
tempFile = 1;
|
tempFile = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the Pager structure. As part of the same allocation, allocate
|
|
||||||
** space for the full paths of the file, directory and journal
|
|
||||||
** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).
|
|
||||||
*/
|
|
||||||
if( zFullPathname ){
|
|
||||||
nameLen = strlen(zFullPathname);
|
|
||||||
pPager = sqlite3MallocZero( sizeof(*pPager) + nameLen*3 + 30 );
|
|
||||||
if( pPager && rc==SQLITE_OK ){
|
if( pPager && rc==SQLITE_OK ){
|
||||||
pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE);
|
pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If an error occured in either of the blocks above, free the memory
|
/* If an error occured in either of the blocks above, free the memory
|
||||||
** pointed to by zFullPathname, free the Pager structure and close the
|
** pointed to by zFullPathname, free the Pager structure and close the
|
||||||
** file. Since the pager is not allocated there is no need to set
|
** file. Since the pager is not allocated there is no need to set
|
||||||
** any Pager.errMask variables.
|
** any Pager.errMask variables.
|
||||||
*/
|
*/
|
||||||
if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){
|
if( !pPager || !pPager->pTmpSpace ){
|
||||||
sqlite3OsClose(&fd);
|
sqlite3OsClose(pPager->fd);
|
||||||
sqlite3_free(zFullPathname);
|
|
||||||
sqlite3_free(pPager);
|
sqlite3_free(pPager);
|
||||||
return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
|
return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
|
PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
|
||||||
IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))
|
IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))
|
||||||
pPager->zFilename = (char*)&pPager[1];
|
|
||||||
pPager->zDirectory = &pPager->zFilename[nameLen+1];
|
|
||||||
pPager->zJournal = &pPager->zDirectory[nameLen+1];
|
|
||||||
memcpy(pPager->zFilename, zFullPathname, nameLen+1);
|
|
||||||
memcpy(pPager->zDirectory, zFullPathname, nameLen+1);
|
|
||||||
|
|
||||||
for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
|
/* Fill in Pager.zDirectory[] */
|
||||||
|
memcpy(pPager->zDirectory, pPager->zFilename, pVfs->mxPathname);
|
||||||
|
for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){}
|
||||||
if( i>0 ) pPager->zDirectory[i-1] = 0;
|
if( i>0 ) pPager->zDirectory[i-1] = 0;
|
||||||
memcpy(pPager->zJournal, zFullPathname,nameLen);
|
|
||||||
sqlite3_free(zFullPathname);
|
/* Fill in Pager.zJournal[] */
|
||||||
memcpy(&pPager->zJournal[nameLen], "-journal",sizeof("-journal"));
|
memcpy(pPager->zJournal, pPager->zFilename, pVfs->mxPathname);
|
||||||
pPager->fd = fd;
|
memcpy(&pPager->zJournal[strlen(pPager->zJournal)], "-journal", 9);
|
||||||
|
|
||||||
/* pPager->journalOpen = 0; */
|
/* pPager->journalOpen = 0; */
|
||||||
pPager->useJournal = useJournal && !memDb;
|
pPager->useJournal = useJournal && !memDb;
|
||||||
pPager->noReadlock = noReadlock && readOnly;
|
pPager->noReadlock = noReadlock && readOnly;
|
||||||
@@ -1846,7 +1882,7 @@ int sqlite3PagerOpen(
|
|||||||
/* pPager->pFirstSynced = 0; */
|
/* pPager->pFirstSynced = 0; */
|
||||||
/* pPager->pLast = 0; */
|
/* pPager->pLast = 0; */
|
||||||
pPager->nExtra = FORCE_ALIGNMENT(nExtra);
|
pPager->nExtra = FORCE_ALIGNMENT(nExtra);
|
||||||
assert(fd||memDb);
|
assert(pPager->fd->pMethods||memDb);
|
||||||
if( !memDb ){
|
if( !memDb ){
|
||||||
setSectorSize(pPager);
|
setSectorSize(pPager);
|
||||||
}
|
}
|
||||||
@@ -2229,13 +2265,13 @@ int sqlite3PagerClose(Pager *pPager){
|
|||||||
IOTRACE(("CLOSE %p\n", pPager))
|
IOTRACE(("CLOSE %p\n", pPager))
|
||||||
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
|
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
|
||||||
if( pPager->journalOpen ){
|
if( pPager->journalOpen ){
|
||||||
sqlite3OsClose(&pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
}
|
}
|
||||||
sqlite3_free(pPager->aInJournal);
|
sqlite3_free(pPager->aInJournal);
|
||||||
if( pPager->stmtOpen ){
|
if( pPager->stmtOpen ){
|
||||||
sqlite3OsClose(&pPager->stfd);
|
sqlite3OsClose(pPager->stfd);
|
||||||
}
|
}
|
||||||
sqlite3OsClose(&pPager->fd);
|
sqlite3OsClose(pPager->fd);
|
||||||
/* Temp files are automatically deleted by the OS
|
/* Temp files are automatically deleted by the OS
|
||||||
** if( pPager->tempFile ){
|
** if( pPager->tempFile ){
|
||||||
** sqlite3OsDelete(pPager->zFilename);
|
** sqlite3OsDelete(pPager->zFilename);
|
||||||
@@ -2579,15 +2615,16 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
|
|||||||
** database with the same name. Just delete the journal.
|
** database with the same name. Just delete the journal.
|
||||||
*/
|
*/
|
||||||
static int hasHotJournal(Pager *pPager){
|
static int hasHotJournal(Pager *pPager){
|
||||||
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
if( !pPager->useJournal ) return 0;
|
if( !pPager->useJournal ) return 0;
|
||||||
if( !sqlite3OsFileExists(pPager->zJournal) ){
|
if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( sqlite3OsCheckReservedLock(pPager->fd) ){
|
if( sqlite3OsCheckReservedLock(pPager->fd) ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( sqlite3PagerPagecount(pPager)==0 ){
|
if( sqlite3PagerPagecount(pPager)==0 ){
|
||||||
sqlite3OsDelete(pPager->zJournal);
|
sqlite3OsDelete(pVfs, pPager->zJournal);
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2702,9 +2739,11 @@ int sqlite3PagerReleaseMemory(int nReq){
|
|||||||
** some of the code invoked by this function may also
|
** some of the code invoked by this function may also
|
||||||
** try to obtain the mutex, resulting in a deadlock.
|
** try to obtain the mutex, resulting in a deadlock.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
if( sqlite3OsInMutex(0) ){
|
if( sqlite3OsInMutex(0) ){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Outermost loop runs for at most two iterations. First iteration we
|
/* Outermost loop runs for at most two iterations. First iteration we
|
||||||
** try to find memory that can be released without calling fsync(). Second
|
** try to find memory that can be released without calling fsync(). Second
|
||||||
@@ -2817,6 +2856,7 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
if( pPager->state==PAGER_UNLOCK ){
|
if( pPager->state==PAGER_UNLOCK ){
|
||||||
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
if( !MEMDB ){
|
if( !MEMDB ){
|
||||||
assert( pPager->nRef==0 );
|
assert( pPager->nRef==0 );
|
||||||
if( !pPager->noReadlock ){
|
if( !pPager->noReadlock ){
|
||||||
@@ -2864,14 +2904,15 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
** a read/write file handle.
|
** a read/write file handle.
|
||||||
*/
|
*/
|
||||||
rc = SQLITE_BUSY;
|
rc = SQLITE_BUSY;
|
||||||
if( sqlite3OsFileExists(pPager->zJournal) ){
|
if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
|
||||||
int ro;
|
int fout = 0;
|
||||||
|
int flags = SQLITE_OPEN_READWRITE;
|
||||||
assert( !pPager->tempFile );
|
assert( !pPager->tempFile );
|
||||||
rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro);
|
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, &fout);
|
||||||
assert( rc!=SQLITE_OK || pPager->jfd );
|
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
||||||
if( ro ){
|
if( fout&SQLITE_OPEN_READONLY ){
|
||||||
rc = SQLITE_BUSY;
|
rc = SQLITE_BUSY;
|
||||||
sqlite3OsClose(&pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -3294,6 +3335,9 @@ int sqlite3PagerUnref(DbPage *pPg){
|
|||||||
** write lock if anything goes wrong.
|
** write lock if anything goes wrong.
|
||||||
*/
|
*/
|
||||||
static int pager_open_journal(Pager *pPager){
|
static int pager_open_journal(Pager *pPager){
|
||||||
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
|
int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
assert( !MEMDB );
|
assert( !MEMDB );
|
||||||
assert( pPager->state>=PAGER_RESERVED );
|
assert( pPager->state>=PAGER_RESERVED );
|
||||||
@@ -3306,15 +3350,18 @@ static int pager_open_journal(Pager *pPager){
|
|||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto failed_to_open_journal;
|
goto failed_to_open_journal;
|
||||||
}
|
}
|
||||||
rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
|
|
||||||
pPager->tempFile);
|
if( pPager->tempFile ){
|
||||||
assert( rc!=SQLITE_OK || pPager->jfd );
|
flags |= SQLITE_OPEN_DELETEONCLOSE;
|
||||||
|
}
|
||||||
|
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
|
||||||
|
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
||||||
pPager->journalOff = 0;
|
pPager->journalOff = 0;
|
||||||
pPager->setMaster = 0;
|
pPager->setMaster = 0;
|
||||||
pPager->journalHdr = 0;
|
pPager->journalHdr = 0;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
if( rc==SQLITE_NOMEM ){
|
if( rc==SQLITE_NOMEM ){
|
||||||
sqlite3OsDelete(pPager->zJournal);
|
sqlite3OsDelete(pVfs, pPager->zJournal);
|
||||||
}
|
}
|
||||||
goto failed_to_open_journal;
|
goto failed_to_open_journal;
|
||||||
}
|
}
|
||||||
@@ -4180,7 +4227,7 @@ int sqlite3PagerStmtBegin(Pager *pPager){
|
|||||||
pPager->stmtHdrOff = 0;
|
pPager->stmtHdrOff = 0;
|
||||||
pPager->stmtCksum = pPager->cksumInit;
|
pPager->stmtCksum = pPager->cksumInit;
|
||||||
if( !pPager->stmtOpen ){
|
if( !pPager->stmtOpen ){
|
||||||
rc = sqlite3PagerOpentemp(&pPager->stfd);
|
rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, 0);
|
||||||
if( rc ) goto stmt_begin_failed;
|
if( rc ) goto stmt_begin_failed;
|
||||||
pPager->stmtOpen = 1;
|
pPager->stmtOpen = 1;
|
||||||
pPager->stmtNRec = 0;
|
pPager->stmtNRec = 0;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** subsystem. The page cache subsystem reads and writes a file a page
|
** subsystem. The page cache subsystem reads and writes a file a page
|
||||||
** at a time and provides a journal for rollback.
|
** at a time and provides a journal for rollback.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.h,v 1.61 2007/05/08 21:45:28 drh Exp $
|
** @(#) $Id: pager.h,v 1.62 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PAGER_H_
|
#ifndef _PAGER_H_
|
||||||
@@ -54,8 +54,7 @@ typedef struct PgHdr DbPage;
|
|||||||
** See source code comments for a detailed description of the following
|
** See source code comments for a detailed description of the following
|
||||||
** routines:
|
** routines:
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerOpen(Pager **ppPager, const char *zFilename,
|
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char *, int, int);
|
||||||
int nExtra, int flags);
|
|
||||||
void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
|
void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
|
||||||
void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
|
void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
|
||||||
void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int));
|
void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int));
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.144 2007/08/16 10:09:03 danielk1977 Exp $
|
** $Id: pragma.c,v 1.145 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -557,7 +557,9 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){
|
if( zRight[0]
|
||||||
|
&& !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE)
|
||||||
|
){
|
||||||
sqlite3ErrorMsg(pParse, "not a writable directory");
|
sqlite3ErrorMsg(pParse, "not a writable directory");
|
||||||
goto pragma_out;
|
goto pragma_out;
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
** Random numbers are used by some of the database backends in order
|
** Random numbers are used by some of the database backends in order
|
||||||
** to generate random integer keys for tables or random filenames.
|
** to generate random integer keys for tables or random filenames.
|
||||||
**
|
**
|
||||||
** $Id: random.c,v 1.16 2007/01/05 14:38:56 drh Exp $
|
** $Id: random.c,v 1.17 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -63,7 +63,7 @@ static int randomByte(void){
|
|||||||
char k[256];
|
char k[256];
|
||||||
prng.j = 0;
|
prng.j = 0;
|
||||||
prng.i = 0;
|
prng.i = 0;
|
||||||
sqlite3OsRandomSeed(k);
|
sqlite3OsRandomness(sqlite3_find_vfs(0), 256, k);
|
||||||
for(i=0; i<256; i++){
|
for(i=0; i<256; i++){
|
||||||
prng.s[i] = i;
|
prng.s[i] = i;
|
||||||
}
|
}
|
||||||
@@ -92,9 +92,9 @@ static int randomByte(void){
|
|||||||
*/
|
*/
|
||||||
void sqlite3Randomness(int N, void *pBuf){
|
void sqlite3Randomness(int N, void *pBuf){
|
||||||
unsigned char *zBuf = pBuf;
|
unsigned char *zBuf = pBuf;
|
||||||
sqlite3OsEnterMutex();
|
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_PRNG));
|
||||||
while( N-- ){
|
while( N-- ){
|
||||||
*(zBuf++) = randomByte();
|
*(zBuf++) = randomByte();
|
||||||
}
|
}
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_PRNG));
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
** the version number) and changes its name to "sqlite3.h" as
|
** the version number) and changes its name to "sqlite3.h" as
|
||||||
** part of the build process.
|
** part of the build process.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.227 2007/08/17 01:14:38 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.228 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE3_H_
|
#ifndef _SQLITE3_H_
|
||||||
#define _SQLITE3_H_
|
#define _SQLITE3_H_
|
||||||
@@ -644,10 +644,10 @@ struct sqlite3_vfs {
|
|||||||
int (*xAccess)(void *pAppData, const char *zName, int flags);
|
int (*xAccess)(void *pAppData, const char *zName, int flags);
|
||||||
int (*xGetTempName)(void *pAppData, char *zOut);
|
int (*xGetTempName)(void *pAppData, char *zOut);
|
||||||
int (*xFullPathname)(void *pAppData, const char *zName, char *zOut);
|
int (*xFullPathname)(void *pAppData, const char *zName, char *zOut);
|
||||||
void *(*xDlOpen)(void *pAppData, char *zFilename);
|
void *(*xDlOpen)(void *pAppData, const char *zFilename);
|
||||||
void (*xDlError)(void*, int nByte, char *zErrMsg);
|
void (*xDlError)(void *pAppData, int nByte, char *zErrMsg);
|
||||||
void *(*xDlSym)(void*, const char *zSymbol);
|
void *(*xDlSym)(void*, const char *zSymbol);
|
||||||
void (*xDlclose)(void*);
|
void (*xDlClose)(void*);
|
||||||
int (*xRandomness)(void *pAppData, int nByte, char *zOut);
|
int (*xRandomness)(void *pAppData, int nByte, char *zOut);
|
||||||
int (*xSleep)(void *pAppData, int microseconds);
|
int (*xSleep)(void *pAppData, int microseconds);
|
||||||
int (*xCurrentTime)(void *pAppData, double*);
|
int (*xCurrentTime)(void *pAppData, double*);
|
||||||
@@ -655,6 +655,10 @@ struct sqlite3_vfs {
|
|||||||
** value will increment whenever this happens. */
|
** value will increment whenever this happens. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SQLITE_ACCESS_EXISTS 0
|
||||||
|
#define SQLITE_ACCESS_READWRITE 1
|
||||||
|
#define SQLITE_ACCESS_READONLY 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||||
**
|
**
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.590 2007/08/17 01:14:38 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.591 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -187,7 +187,7 @@ typedef UINT8_TYPE i8; /* 1-byte signed integer */
|
|||||||
*/
|
*/
|
||||||
#define SQLITE_MUTEX_MEM 1 /* Used by the memory allocator */
|
#define SQLITE_MUTEX_MEM 1 /* Used by the memory allocator */
|
||||||
#define SQLITE_MUTEX_PRNG 2 /* Used by pseudorandom generator */
|
#define SQLITE_MUTEX_PRNG 2 /* Used by pseudorandom generator */
|
||||||
#define SQLITE_MUTEX_CACHE 3 /* Used by shared cache */
|
#define SQLITE_MUTEX_GLOBAL 3 /* Used by global variables */
|
||||||
#define SQLITE_MUTEX_STATIC_MAX 3
|
#define SQLITE_MUTEX_STATIC_MAX 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.263 2007/08/17 01:14:38 drh Exp $
|
** $Id: test1.c,v 1.264 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -3587,6 +3587,7 @@ static int test_stmt_int(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
** Usage: sqlite3OsOpenReadWrite <filename>
|
** Usage: sqlite3OsOpenReadWrite <filename>
|
||||||
*/
|
*/
|
||||||
@@ -3744,6 +3745,7 @@ static int test_sqlite3OsTempFileName(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Usage: sqlite_set_magic DB MAGIC-NUMBER
|
** Usage: sqlite_set_magic DB MAGIC-NUMBER
|
||||||
@@ -4285,6 +4287,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
|
|
||||||
/* Functions from os.h */
|
/* Functions from os.h */
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
|
#if 0
|
||||||
{ "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
|
{ "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
|
||||||
{ "sqlite3OsClose", test_sqlite3OsClose, 0 },
|
{ "sqlite3OsClose", test_sqlite3OsClose, 0 },
|
||||||
{ "sqlite3OsLock", test_sqlite3OsLock, 0 },
|
{ "sqlite3OsLock", test_sqlite3OsLock, 0 },
|
||||||
@@ -4293,6 +4296,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
/* Custom test interfaces */
|
/* Custom test interfaces */
|
||||||
{ "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 },
|
{ "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 },
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
{ "add_test_collate", test_collate, 0 },
|
{ "add_test_collate", test_collate, 0 },
|
||||||
{ "add_test_collate_needed", test_collate_needed, 0 },
|
{ "add_test_collate_needed", test_collate_needed, 0 },
|
||||||
|
15
src/test2.c
15
src/test2.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test2.c,v 1.45 2007/08/16 10:09:03 danielk1977 Exp $
|
** $Id: test2.c,v 1.46 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -78,7 +78,7 @@ static int pager_open(
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
|
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
|
||||||
rc = sqlite3PagerOpen(&pPager, argv[1], 0, 0);
|
rc = sqlite3PagerOpen(sqlite3_find_vfs(0), &pPager, argv[1], 0, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
@@ -528,18 +528,21 @@ static int fake_big_file(
|
|||||||
int argc, /* Number of arguments */
|
int argc, /* Number of arguments */
|
||||||
const char **argv /* Text of each argument */
|
const char **argv /* Text of each argument */
|
||||||
){
|
){
|
||||||
|
sqlite3_vfs *pVfs;
|
||||||
|
sqlite3_file *fd = 0;
|
||||||
|
int flags = SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
|
||||||
int rc;
|
int rc;
|
||||||
int n;
|
int n;
|
||||||
i64 offset;
|
i64 offset;
|
||||||
sqlite3_file *fd = 0;
|
|
||||||
int readOnly = 0;
|
|
||||||
if( argc!=3 ){
|
if( argc!=3 ){
|
||||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||||
" N-MEGABYTES FILE\"", 0);
|
" N-MEGABYTES FILE\"", 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
|
if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
|
||||||
rc = sqlite3OsOpenReadWrite(argv[2], &fd, &readOnly);
|
|
||||||
|
pVfs = sqlite3_find_vfs(0);
|
||||||
|
rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, flags);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
|
Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
@@ -547,7 +550,7 @@ static int fake_big_file(
|
|||||||
offset = n;
|
offset = n;
|
||||||
offset *= 1024*1024;
|
offset *= 1024*1024;
|
||||||
rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
|
rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
|
||||||
sqlite3OsClose(&fd);
|
sqlite3OsCloseFree(fd);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
|
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
|
30
src/test6.c
30
src/test6.c
@@ -263,7 +263,7 @@ static int writeListAppend(
|
|||||||
|
|
||||||
assert((zBuf && nBuf) || (!nBuf && !zBuf));
|
assert((zBuf && nBuf) || (!nBuf && !zBuf));
|
||||||
|
|
||||||
pNew = (WriteBuffer *)sqlite3_malloc(sizeof(WriteBuffer) + nBuf);
|
pNew = (WriteBuffer *)sqlite3MallocZero(sizeof(WriteBuffer) + nBuf);
|
||||||
pNew->iOffset = iOffset;
|
pNew->iOffset = iOffset;
|
||||||
pNew->nBuf = nBuf;
|
pNew->nBuf = nBuf;
|
||||||
pNew->pFile = (CrashFile *)pFile;
|
pNew->pFile = (CrashFile *)pFile;
|
||||||
@@ -544,8 +544,8 @@ static int crashParamsObjCmd(
|
|||||||
int objc,
|
int objc,
|
||||||
Tcl_Obj *CONST objv[]
|
Tcl_Obj *CONST objv[]
|
||||||
){
|
){
|
||||||
|
sqlite3_vfs *pVfs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int iDelay;
|
int iDelay;
|
||||||
const char *zCrashFile;
|
const char *zCrashFile;
|
||||||
int nCrashFile;
|
int nCrashFile;
|
||||||
@@ -575,17 +575,19 @@ static int crashParamsObjCmd(
|
|||||||
|
|
||||||
if( objc<3 ){
|
if( objc<3 ){
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE");
|
Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE");
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
zCrashFile = sqlite3OsFullPathname(Tcl_GetString(objv[objc-1]));
|
pVfs = sqlite3_find_vfs(0);
|
||||||
|
zCrashFile = sqlite3_malloc(pVfs->mxPathname);
|
||||||
|
sqlite3OsFullPathname(pVfs, Tcl_GetString(objv[objc-1]), zCrashFile);
|
||||||
nCrashFile = strlen(zCrashFile);
|
nCrashFile = strlen(zCrashFile);
|
||||||
if( nCrashFile>=sizeof(g.zCrashFile) ){
|
if( nCrashFile>=sizeof(g.zCrashFile) ){
|
||||||
Tcl_AppendResult(interp, "Filename is too long: \"", zCrashFile, "\"", 0);
|
Tcl_AppendResult(interp, "Filename is too long: \"", zCrashFile, "\"", 0);
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
if( Tcl_GetIntFromObj(interp, objv[objc-2], &iDelay) ){
|
if( Tcl_GetIntFromObj(interp, objv[objc-2], &iDelay) ){
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=1; i<(objc-2); i+=2){
|
for(i=1; i<(objc-2); i+=2){
|
||||||
@@ -599,16 +601,16 @@ static int crashParamsObjCmd(
|
|||||||
"Bad option: \"", zOpt,
|
"Bad option: \"", zOpt,
|
||||||
"\" - must be \"-characteristics\" or \"-sectorsize\"", 0
|
"\" - must be \"-characteristics\" or \"-sectorsize\"", 0
|
||||||
);
|
);
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
if( i==objc-3 ){
|
if( i==objc-3 ){
|
||||||
Tcl_AppendResult(interp, "Option requires an argument: \"", zOpt, "\"",0);
|
Tcl_AppendResult(interp, "Option requires an argument: \"", zOpt, "\"",0);
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( zOpt[1]=='s' ){
|
if( zOpt[1]=='s' ){
|
||||||
if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){
|
if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
setSectorsize = 1;
|
setSectorsize = 1;
|
||||||
}else{
|
}else{
|
||||||
@@ -616,7 +618,7 @@ static int crashParamsObjCmd(
|
|||||||
Tcl_Obj **apObj;
|
Tcl_Obj **apObj;
|
||||||
int nObj;
|
int nObj;
|
||||||
if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){
|
if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
for(j=0; j<nObj; j++){
|
for(j=0; j<nObj; j++){
|
||||||
int rc;
|
int rc;
|
||||||
@@ -630,7 +632,7 @@ static int crashParamsObjCmd(
|
|||||||
);
|
);
|
||||||
Tcl_DecrRefCount(pFlag);
|
Tcl_DecrRefCount(pFlag);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return TCL_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
iDc |= aFlag[iChoice].iValue;
|
iDc |= aFlag[iChoice].iValue;
|
||||||
@@ -647,9 +649,13 @@ static int crashParamsObjCmd(
|
|||||||
}
|
}
|
||||||
g.iCrash = iDelay;
|
g.iCrash = iDelay;
|
||||||
memcpy(g.zCrashFile, zCrashFile, nCrashFile+1);
|
memcpy(g.zCrashFile, zCrashFile, nCrashFile+1);
|
||||||
|
sqlite3_free(zCrashFile);
|
||||||
sqlite3CrashTestEnable = 1;
|
sqlite3CrashTestEnable = 1;
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
sqlite3_free(zCrashFile);
|
||||||
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SQLITE_OMIT_DISKIO */
|
#endif /* SQLITE_OMIT_DISKIO */
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.641 2007/08/16 10:09:03 danielk1977 Exp $
|
** $Id: vdbe.c,v 1.642 2007/08/17 15:53:37 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -486,7 +486,7 @@ int sqlite3VdbeExec(
|
|||||||
sqlite3VdbeIOTraceSql(p);
|
sqlite3VdbeIOTraceSql(p);
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( (p->db->flags & SQLITE_VdbeListing)!=0
|
if( (p->db->flags & SQLITE_VdbeListing)!=0
|
||||||
|| sqlite3OsFileExists("vdbe_explain")
|
|| sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)
|
||||||
){
|
){
|
||||||
int i;
|
int i;
|
||||||
printf("VDBE Program Listing:\n");
|
printf("VDBE Program Listing:\n");
|
||||||
@@ -495,7 +495,7 @@ int sqlite3VdbeExec(
|
|||||||
sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
|
sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( sqlite3OsFileExists("vdbe_trace") ){
|
if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS) ){
|
||||||
p->trace = stdout;
|
p->trace = stdout;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -519,7 +519,8 @@ int sqlite3VdbeExec(
|
|||||||
}
|
}
|
||||||
sqlite3VdbePrintOp(p->trace, pc, pOp);
|
sqlite3VdbePrintOp(p->trace, pc, pOp);
|
||||||
}
|
}
|
||||||
if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
|
if( p->trace==0 && pc==0
|
||||||
|
&& sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS) ){
|
||||||
sqlite3VdbePrintSql(p);
|
sqlite3VdbePrintSql(p);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -221,7 +221,7 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
}
|
}
|
||||||
if( db->xProfile && !db->init.busy ){
|
if( db->xProfile && !db->init.busy ){
|
||||||
double rNow;
|
double rNow;
|
||||||
sqlite3OsCurrentTime(&rNow);
|
sqlite3OsCurrentTime(db->pVfs, &rNow);
|
||||||
p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
|
p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -258,7 +258,7 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
double rNow;
|
double rNow;
|
||||||
u64 elapseTime;
|
u64 elapseTime;
|
||||||
|
|
||||||
sqlite3OsCurrentTime(&rNow);
|
sqlite3OsCurrentTime(db->pVfs, &rNow);
|
||||||
elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
|
elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
|
||||||
assert( p->nOp>0 );
|
assert( p->nOp>0 );
|
||||||
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
assert( p->aOp[p->nOp-1].opcode==OP_Noop );
|
||||||
|
@@ -1132,10 +1132,12 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
else{
|
else{
|
||||||
|
sqlite3_vfs *pVfs = db->pVfs;
|
||||||
|
int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_EXCLUSIVE);
|
||||||
int needSync = 0;
|
int needSync = 0;
|
||||||
char *zMaster = 0; /* File-name for the master journal */
|
char *zMaster = 0; /* File-name for the master journal */
|
||||||
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
|
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
|
||||||
sqlite3_file *master = 0;
|
sqlite3_file *pMaster = 0;
|
||||||
i64 offset = 0;
|
i64 offset = 0;
|
||||||
|
|
||||||
/* Select a master journal file name */
|
/* Select a master journal file name */
|
||||||
@@ -1147,12 +1149,14 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
if( !zMaster ){
|
if( !zMaster ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
}while( sqlite3OsFileExists(zMaster) );
|
}while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) );
|
||||||
|
|
||||||
/* Open the master journal. */
|
/* Open the master journal. */
|
||||||
rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
|
pMaster = sqlite3_malloc(pVfs->szOsFile);
|
||||||
|
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flag, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
|
sqlite3_free(pMaster);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,12 +1175,13 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
|
if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
|
||||||
needSync = 1;
|
needSync = 1;
|
||||||
}
|
}
|
||||||
rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1, offset);
|
rc = sqlite3OsWrite(pMaster, zFile, strlen(zFile)+1, offset);
|
||||||
offset += strlen(zFile)+1;
|
offset += strlen(zFile)+1;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3OsClose(&master);
|
sqlite3OsClose(pMaster);
|
||||||
sqlite3OsDelete(zMaster);
|
sqlite3OsDelete(pVfs, zMaster);
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
|
sqlite3_free(pMaster);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1214,9 +1219,10 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
|
rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3OsClose(&master);
|
sqlite3OsClose(pMaster);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
|
sqlite3_free(pMaster);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1224,13 +1230,17 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
** doing this the directory is synced again before any individual
|
** doing this the directory is synced again before any individual
|
||||||
** transaction files are deleted.
|
** transaction files are deleted.
|
||||||
*/
|
*/
|
||||||
rc = sqlite3OsDelete(zMaster);
|
rc = sqlite3OsDelete(pVfs, zMaster);
|
||||||
sqlite3_free(zMaster);
|
sqlite3_free(zMaster);
|
||||||
|
sqlite3_free(pMaster);
|
||||||
zMaster = 0;
|
zMaster = 0;
|
||||||
|
pMaster = 0;
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
rc = sqlite3OsSyncDirectory(zMainFile);
|
rc = sqlite3OsSyncDirectory(zMainFile);
|
||||||
|
#endif
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
/* This is not good. The master journal file has been deleted, but
|
/* This is not good. The master journal file has been deleted, but
|
||||||
** the directory sync failed. There is no completely safe course of
|
** the directory sync failed. There is no completely safe course of
|
||||||
|
Reference in New Issue
Block a user