]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge the patch that enables reading a read-only WAL-mode database, without
authordrh <drh@noemail.net>
Tue, 14 Nov 2017 20:36:33 +0000 (20:36 +0000)
committerdrh <drh@noemail.net>
Tue, 14 Nov 2017 20:36:33 +0000 (20:36 +0000)
any special query parameters, as long as the -shm and -wal files are on disk.

FossilOrigin-Name: 8c2a769c4ac331c20134eb3d0e96f6af21c8ac7529a5eaea4843cce7cf7c936a

1  2 
manifest
manifest.uuid
src/main.c
src/os_unix.c
src/os_win.c
src/sqlite.h.in
src/wal.c
test/wal2.test
test/walro.test

diff --cc manifest
index 7eed5ed22430b6b5e3b0ac0a0919e29fd56b1a8b,f1fb27c3db6aea2ac5bc7080e503d54b7afb6a1c..1ab8e114686ff9284d8551a649bad618332ca46e
+++ b/manifest
@@@ -1,8 -1,8 +1,8 @@@
- C Merge\sall\schanges\sfrom\strunk\sprior\sto\sthe\sread-only\sWAL\senhancement.
- D 2017-11-14T20:00:51.864
 -C Add\sthe\sability\sto\sread\sfrom\sread-only\sWAL-mode\sdatabase\sfiles\sas\slong\sas\nthe\s-wal\sand\s-shm\sfiles\sare\spresent\son\sdisk.
 -D 2017-11-14T19:34:22.764
 -F Makefile.in b142eb20482922153ebc77b261cdfd0a560ed05a81e9f6d9a2b0e8192922a1d2
++C Merge\sthe\spatch\sthat\senables\sreading\sa\sread-only\sWAL-mode\sdatabase,\swithout\nany\sspecial\squery\sparameters,\sas\slong\sas\sthe\s-shm\sand\s-wal\sfiles\sare\son\sdisk.
++D 2017-11-14T20:36:33.703
 +F Makefile.in 28a879888205a67bd3b54c68afa1cd2e939e8ead2179b1177756a101dd1eb86e
  F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 -F Makefile.msc a55372a22454e742ba7c8f6edf05b83213ec01125166ad7dcee0567e2f7fc81b
 +F Makefile.msc 9e7628ad7d33be39ac041e452e47e648ae3d14afbaaa254096e3a4d1d7c1c653
  F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd
  F VERSION 0c10cdfed866fdd2d80434f64f042c3330f1daaed12e54287beb104f04b3faaf
  F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@@ -436,9 -433,9 +436,9 @@@ F src/hash.h ab34c5c54a9e9de2e790b24349
  F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
  F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
  F src/insert.c c7f333547211b8efbac8a72f71adad736b91e655d7bcdfacc737351ecf3c8df2
 -F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 +F src/legacy.c 83f4499122392b1f1527a5180b1e89951bf640611ce98768bde1a9f28f0f7dde
  F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2
- F src/main.c dc25a8bc0fac4853037485867db57d0fecda37abe1c173dbadcfb35f681a7c9b
 -F src/main.c c1965ee8159cee5fba3f590cc4767515a690504455a03e4817b1accfe0ba95a5
++F src/main.c d45e9b657bbf1015ae05a6be2e4b26798a2af0085e9260a5ca5cab4032208a14
  F src/malloc.c a02c9e69bc76bee0f639416b947a946412890b606301454727feadcb313536d6
  F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
  F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@@ -457,29 -454,28 +457,29 @@@ F src/os.c 1975fc1d821a8095c68000728746
  F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
  F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
  F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
- F src/os_unix.c b81670237c9c449c79299fd0e0962572f93700404f1ef11d392032b9e8025fc1
- F src/os_win.c 1473a2ca43202d2511b1f9378614ebfbeccbc02d4cf093f5de06bde470c53165
 -F src/os_unix.c e87cef0bb894b94d96ee3af210be669549d111c580817d14818101b992640767
 -F src/os_win.c 7f36120492e4a23c48d1dd685edf29ae459c6d555660c61f1323cea3e5a1191d
++F src/os_unix.c 50b62dad4ea54c5962d311d94303d1f7f88ce0ac1bdc09b34720a33466f5eee8
++F src/os_win.c f626b26c878e7be2a3393a68291c1d8d1008c2740054044ab12656108b3b766a
  F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 -F src/pager.c 07cf850241667874fcce9d7d924c814305e499b26c804322e2261247b5921903
 -F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
 +F src/pager.c fb3cd08ac0cb9918c77a46dbe51806977d17eaaf561d623ad95fd34b5ec86069
 +F src/pager.h e9718b1a8d0af6162d6818774d95e621fec6f706baa38cc562690b3e4ee0dca0
  F src/parse.y f5f02ef39444982af36545bd52ae2921fc4ba1bac24d9b11efd8ec1f52c5b4dc
  F src/pcache.c 7ae91a4557a43d77d449accbfdc68846e6516f8e2eda46e8bbe4536fb669b201
  F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
 -F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
 -F src/pragma.c d04725ac25387d9638919e197fb009f378e13af7bf899516979e54b3164e3602
 +F src/pcache1.c 77a8848baa3d396b8f597b2e8ba85d82ba00584e45e1c1c27d413712a1b0d88a
 +F src/pragma.c b27a8162733856c2f1c6bff0cfd483f57fd5f6126e13495b09d7c108994e2d30
  F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
 -F src/prepare.c 7cf451f903ad92a14e22de415a13e7a7d30f1bd23b3d21eeb0dc7264723244c5
 +F src/prepare.c a67a7d5ff553978eeda2a5e8722ee1362102c43539902f1f5f4893cad8451954
- F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c
+ F src/printf.c 9506b4b96e59c0467047155f09015750cb2878aeda3d39e5610c1192ddc3c41c
  F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
  F src/resolve.c 5b1e89ba279f4a4ab2f0975a7100d75be71e1a43a2df75a9c909d45bdd18c6ed
  F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
  F src/select.c 660ef7977841fb462f24c8561e4212615bb6e5c9835fd3556257ce8316c50fee
  F src/shell.c.in 08cbffc31900359fea85896342a46147e9772c370d8a5079b7be26e3a1f50e8a
- F src/sqlite.h.in 90bcd1d6824d96baa5605d81be619e55e9f57b3995b321e2c4412f13ec80f148
 -F src/sqlite.h.in 8fd97993d48b50b9bade38c52f12d175942c9497c960905610c7b03a3e4b5818
++F src/sqlite.h.in d91e91266f023109e46160119cfd31490a11fe7006204dbf004f774b535fe1b8
  F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 +F src/sqlite3_private.h a81a9c5f97c095cc3e86914a05f8fabe0011f4a1
  F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
 -F src/sqliteInt.h abd4e64bc72906449d801d0e211265525239bc021bd9b7a72143c281fc24fa03
 +F src/sqliteInt.h 29a73df20d410157df6a2317662c2fe7f4c601af2f1b2685cd37666c0bfe70c6
  F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
  F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
  F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@@ -554,8 -550,8 +554,8 @@@ F src/vdbesort.c 731a09e5cb9e96b70c394c
  F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c
  F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
  F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
- F src/wal.c ec9f4e5d06c14e144dc5419a12d47ecbf7d47d43d718456cff79039dcc627b8f
 -F src/wal.c beeb71e4eab65dbf0d95f2717efc6ca3c0f5b3090ce67f3de63828f39a6ff053
 -F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
++F src/wal.c f940fd2e63228dede53d56a29364831f5a3f9e24232fbb9a6db3baec01f95f36
 +F src/wal.h bada9007800e82f2765ad9ecd9f96176b45c71db769502e24de49d68c0acef65
  F src/walker.c d591e8a9ccf60abb010966b354fcea4aa08eba4d83675c2b281a8764c76cc22f
  F src/where.c 031a80bcafe93934fd7052f3031c9e7eb36b61754c6c84d6bf0833184abad3db
  F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
@@@ -1511,36 -1506,38 +1511,38 @@@ F test/vtabJ.test d7b73675708cf63cfcb9d
  F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
  F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
  F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
 -F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
 -F test/wal2.test 2d81ffe2a02d9e5c7447b266f7153716cfcba7aecda5ed832db4544617399e29
 -F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
 -F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
 -F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
 -F test/wal6.test b602704e4b066199bc89d91ca9000f335dcf4572
 +F test/wal.test 83635d428b0a3fe883939cedbaedf29e13a5affd
- F test/wal2.test 798688af58a245cbee8e2eab424bfdf9cc5bd80ba6f8d3bed70d994af8a33810
++F test/wal2.test de1182f52eda816f298b678f4721eb4fecba7ac99d2a72d60cd41b88b83746e4
 +F test/wal3.test 82f70ca79e5db6829f9246f4a30d4a4751921c3b
 +F test/wal4.test 5755887f321baa4c55de0b91066fa7d0cafcac9d
 +F test/wal5.test 9304fada875d7279deb2783385b0ae1c02d96b88
 +F test/wal6.test 3d9b79194d15f5b4f6e4169f89f815c049edb2df
  F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
 -F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
 -F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8
 +F test/wal7.test 18cf68ab8010ae0a2baaa48e5b59567a9503e63e
 +F test/wal8.test 82bf6e493002b2d1580823b40e47bce3e15f468a
  F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
 -F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
 -F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946
 -F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
 +F test/wal_common.tcl 15f152fd55703975878741beca6cfa4209d5b3b3
 +F test/walbak.test e322af729156c121183af4847c6e2b17bc629f47
 +F test/walbig.test 3ca3d94751b80054eed5bda20a1339ae1f619483
  F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d
 -F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278
 -F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a
 -F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
 -F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
 +F test/walcksum.test add42a54d7c7d9bc72a913792022a195293bef2b
 +F test/walcrash.test 065a041da88f980df3830f09b7fe308337bb594a
 +F test/walcrash2.test 6eb6842d34cc5955726264c80566963c32a9cbea
 +F test/walcrash3.test 279640ffafa23f7564529ccd69bfb97849ccae9d
  F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20
 -F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
 -F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
 -F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
 -F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
 +F test/walfault.test f4160abd02d583d06d7ea9554e7a3f749f6b3410
 +F test/walhook.test 5d2bdb04fd3e220e2f96e6b566d57e00020bdaec
 +F test/walmode.test aa45339b4afa435dde5d88e71a95459cc221a3f4
 +F test/walnoshm.test 559b878f3aab838971d820329ca35f1caa7b038e
  F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
 -F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
 +F test/walpersist.test abd956d66e2f36d2d9d05d3a969f48be6d2ddbec
  F test/walprotocol.test 0b92feb132ccebd855494d917d3f6c2d717ace20
- F test/walro.test b874ef49167c3a463f798a4caf25c7e13e1a9e7f
 -F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
++F test/walro.test cac7fa52dffec99f15c6e266769628d711935e4064dbcd7466ce3479b5011eb5
+ F test/walro2.test 8812e514c968bf4ee317571fafedac43443360ae23edd7d0f4ef1eae0c13e8e8
+ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
 -F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
 -F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
 -F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
 +F test/walshared.test 04590b10c677f75318701818c50bc0dda5da64ab
 +F test/walslow.test 07a51cbe9d4895d0a90c7af76d14a62d363ac162
 +F test/walthread.test c13f5a12fbd9d81e58f49875dc9dd8a52a84cf03
  F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757
  F test/where2.test 478d2170637b9211f593120648858593bf2445a1
  F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1
@@@ -1680,7 -1677,8 +1682,7 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9
  F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
  F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
  F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P 13be3a441dc8d856a9d372aaf695fe346727cfcaa0ed763a7b8537a5ffbb5a80 dae4a97a483bee1e6ac0271ddd28a0dffcebf7522edaf12eb5e0eba5fc62516a
- R f0a5759552f6352d54efb56eeb2c1f17
 -P dae4a97a483bee1e6ac0271ddd28a0dffcebf7522edaf12eb5e0eba5fc62516a 486949fc03706e0056439b52ce60931ea4ce0a65e391da7f6287fe13862de251
 -R 4dd08ae7170c8d270fe307a98bb5bfb2
 -T +closed 486949fc03706e0056439b52ce60931ea4ce0a65e391da7f6287fe13862de251
++P 1754faefccba39900a89bad3d6ba6670a504a1f229621ce3a16eca03ae062e36 00ec95fcd02bb415dabd7f25fee24856d45d6916c18b2728e97e9bb9b8322ba3
++R 2a1beef0243bfb3f51f21af2892b9850
  U drh
- Z 358527010774f58f1b83ab4a162bd65c
 -Z 1fe131254421255cb83ffd7abf325441
++Z 393c94cd8c1fefab07b43a474d449ce1
diff --cc manifest.uuid
index 1678f4c14c393869c1cf2499b727b5ad96375164,1aae26850e9d947d18548432b90e1efac79a8c89..3c4560659dfcbddca732661b8eb2e67ef8b402d6
@@@ -1,1 -1,1 +1,1 @@@
- 1754faefccba39900a89bad3d6ba6670a504a1f229621ce3a16eca03ae062e36
 -00ec95fcd02bb415dabd7f25fee24856d45d6916c18b2728e97e9bb9b8322ba3
++8c2a769c4ac331c20134eb3d0e96f6af21c8ac7529a5eaea4843cce7cf7c936a
diff --cc src/main.c
Simple merge
diff --cc src/os_unix.c
index f0510607146d21bfd5f6e9610796304db279e0ac,c5d9aca2c62ec87b150c39eeb873ac4e77889f4a..c1298ef1457c16e14ff5cca4ff0d820f4bcfa6fc
@@@ -5001,10 -4271,64 +5002,68 @@@ static void unixShmPurge(unixFile *pFd)
    }
  }
  
+ /*
+ ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+ ** take it now. Return SQLITE_OK if successful, or an SQLite error
+ ** code otherwise.
+ **
+ ** If the DMS cannot be locked because this is a readonly_shm=1 
+ ** connection and no other process already holds a lock, return
+ ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+ */
+ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
+   struct flock lock;
+   int rc = SQLITE_OK;
+   /* Use F_GETLK to determine the locks other processes are holding
+   ** on the DMS byte. If it indicates that another process is holding
+   ** a SHARED lock, then this process may also take a SHARED lock
+   ** and proceed with opening the *-shm file. 
+   **
+   ** Or, if no other process is holding any lock, then this process
+   ** is the first to open it. In this case take an EXCLUSIVE lock on the
+   ** DMS byte and truncate the *-shm file to zero bytes in size. Then
+   ** downgrade to a SHARED lock on the DMS byte.
+   **
+   ** If another process is holding an EXCLUSIVE lock on the DMS byte,
+   ** return SQLITE_BUSY to the caller (it will try again). An earlier
+   ** version of this code attempted the SHARED lock at this point. But
+   ** this introduced a subtle race condition: if the process holding
+   ** EXCLUSIVE failed just before truncating the *-shm file, then this
+   ** process might open and use the *-shm file without truncating it.
+   ** And if the *-shm file has been corrupted by a power failure or
+   ** system crash, the database itself may also become corrupt.  */
+   lock.l_whence = SEEK_SET;
+   lock.l_start = UNIX_SHM_DMS;
+   lock.l_len = 1;
+   lock.l_type = F_WRLCK;
+   if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
+     rc = SQLITE_IOERR_LOCK;
+   }else if( lock.l_type==F_UNLCK ){
+     if( pShmNode->isReadonly ){
+       pShmNode->isUnlocked = 1;
+       rc = SQLITE_READONLY_CANTINIT;
+     }else{
+       rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
+       if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
+         rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
+       }
+     }
+   }else if( lock.l_type==F_WRLCK ){
+     rc = SQLITE_BUSY;
+   }
+   if( rc==SQLITE_OK ){
+     assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
+     rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+   }
+   return rc;
+ }
 +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
 +static const char *proxySharedMemoryBasePath(unixFile *);
 +#endif
 +
  /*
  ** Open a shared-memory area associated with open database file pDbFd.  
  ** This particular implementation uses mmapped files.
@@@ -5122,41 -4431,17 +5181,24 @@@ static int unixOpenSharedMemory(unixFil
      }
  
      if( pInode->bProcessLock==0 ){
-       int openFlags = O_RDWR | O_CREAT;
-       int fd;                     /* File descriptor for *-shm file */
-       if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0)
 +#ifdef __APPLE__
-        /* On MacOS and iOS, avoid even trying to open a read-only SHM file
-        ** for writing, because doing so generates scary log messages */
-        || (osAccess(zShmFilename, R_OK|W_OK)!=0
-             && (errno==EPERM || errno==EACCES))
++      /* On MacOS and iOS, avoid even trying to open a read-only SHM file
++      ** for writing, because doing so generates scary log messages */
++      if( osAccess(zShmFilename, R_OK|W_OK)!=0 && (errno==EPERM || errno==EACCES) ){
++        pShmNode->h = -1;
++      }else
 +#endif
-       ){
-         openFlags = O_RDONLY;
-         pShmNode->isReadonly = 1;
+       if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+         pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
        }
-       fd = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
-       /* If it was not possible to open the *-shm file in read/write mode,
-       ** and the database file itself has been opened in read-only mode,
-       ** try to open the *-shm file in read-only mode as well. Even if the
-       ** database connection is read-only, it is still better to try opening
-       ** the *-shm file in read/write mode first, as the same file descriptor
-       ** may be also be used by a read/write database connection.  */
- #if defined(SQLITE_ENABLE_PERSIST_WAL)&&(SQLITE_ENABLE_LOCKING_STYLE \
-     || defined(__APPLE__))
-       if( fd<0 && (errno==EPERM || errno==EACCES) && pShmNode->isReadonly==0 
-        && (pDbFd->openFlags & O_RDWR)!=O_RDWR
-       ){
-         fd = robust_open(zShmFilename, O_RDONLY, (sStat.st_mode&0777));
+       if( pShmNode->h<0 ){
+         pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+         if( pShmNode->h<0 ){
+           rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
+           goto shm_open_err;
+         }
          pShmNode->isReadonly = 1;
        }
- #endif
-       if( fd<0 ){
-         rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
-         goto shm_open_err;
-       }
-       pShmNode->h = fd;
  
        /* If this process is running as root, make sure that the SHM file
        ** is owned by the same user that owns the original database.  Otherwise,
diff --cc src/os_win.c
Simple merge
diff --cc src/sqlite.h.in
Simple merge
diff --cc src/wal.c
Simple merge
diff --cc test/wal2.test
Simple merge
diff --cc test/walro.test
index 2076f06ee96559771167e3cef58a0ab793557411,cae52db6d36f6c5c5cb9078cde060073546913fd..178fdc368004995d4aff181b09f8997feff81319
@@@ -107,27 -99,28 +107,28 @@@ do_multiclient_test tn 
    do_test 1.2.1 {
      code2 { db2 close }
      code1 { db close }
 -    list [file exists test.db-wal] [file exists test.db-shm]
 +    list [file exists test.db-wal] [file exists $shmpath]
    } {1 1}
    do_test 1.2.2 {
      code1 { sqlite3 db file:test.db?readonly_shm=1 }
-     sql1 { SELECT * FROM t1 }
-   } {a b c d e f g h i j}
+     list [catch { sql1 { SELECT * FROM t1 } } msg] $msg
+   } {0 {a b c d e f g h i j}}
  
    do_test 1.2.3 {
      code1 { db close }
 -    file attributes test.db-shm -permissions rw-r--r--
 -    hexio_write test.db-shm 0 01020304 
 -    file attributes test.db-shm -permissions r--r--r--
 +    file attributes $shmpath -permissions rw-r--r--
 +    hexio_write $shmpath 0 01020304
 +    file attributes $shmpath -permissions r--r--r--
      code1 { sqlite3 db file:test.db?readonly_shm=1 }
      csql1 { SELECT * FROM t1 }
-   } {1 {attempt to write a readonly database}}
+   } {0 {a b c d e f g h i j}}
    do_test 1.2.4 {
      code1 { sqlite3_extended_errcode db } 
-   } {SQLITE_READONLY_RECOVERY}
+   } {SQLITE_OK}
  
    do_test 1.2.5 {
 -    file attributes test.db-shm -permissions rw-r--r--
 +    file attributes $shmpath -permissions rw-r--r--
      code2 { sqlite3 db2 test.db }
      sql2 "SELECT * FROM t1" 
    } {a b c d e f g h i j}
    } {1 {unable to open database file}}
    do_test 1.3.2.3 {
      code1 { db close }
 -    close [open test.db-shm w]
 -    file attributes test.db-shm -permissions r--r--r--
 +    close [open $shmpath w]
 +    file attributes $shmpath -permissions r--r--r--
      code1 { sqlite3 db file:test.db?readonly_shm=1 }
      csql1 { SELECT * FROM t1 }
-   } {1 {attempt to write a readonly database}}
+   } {0 {a b c d e f g h i j k l}}
    do_test 1.3.2.4 {
      code1 { sqlite3_extended_errcode db } 
-   } {SQLITE_READONLY_RECOVERY}
+   } {SQLITE_OK}
  
    #-----------------------------------------------------------------------
    # Test cases 1.4.* check that checkpoints and log wraps don't prevent