]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Actually look at i-node numbers to determine whether or not the database
authordrh <drh@noemail.net>
Sat, 7 Dec 2013 12:29:22 +0000 (12:29 +0000)
committerdrh <drh@noemail.net>
Sat, 7 Dec 2013 12:29:22 +0000 (12:29 +0000)
file has moved.

FossilOrigin-Name: 2b1884dc14f9a04a04eebb3245fbe0daaff399eb

manifest
manifest.uuid
src/os_unix.c
src/pager.c
src/sqlite.h.in
test/pager4.test

index d7e2f428538e3ffa69c4b51a7587ac68fcb3d3eb..adb35d7204731c21dba2c7a77470f90ac2f46688 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sSQLITE_READONLY_DBMOVED\serror\scode\sto\sthe\ssqlite3ErrName()\sfunction.
-D 2013-12-06T19:58:32.556
+C Actually\slook\sat\si-node\snumbers\sto\sdetermine\swhether\sor\snot\sthe\sdatabase\nfile\shas\smoved.
+D 2013-12-07T12:29:22.514
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -205,9 +205,9 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
 F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
 F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
-F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f
+F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f
 F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004
-F src/pager.c 938874307e1b07a98a181cbab41c5625f2aa1666
+F src/pager.c 6aa7d8eca75cac90f90f4c2619fb6c47153756e6
 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
 F src/parse.y acee1a9958539e21263362b194594c5255ad2fca
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
@@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a
 F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758
-F src/sqlite.h.in 5ae0618d16a393ff8e66d1e373d3670892c2d254
+F src/sqlite.h.in eea3f417059c203f450ec64acbb19e6201063c0c
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
 F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c
@@ -726,7 +726,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
-F test/pager4.test afbffa3f6813bd9bf126eb5e66bc954717f36de5
+F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642
 F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff
 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
 F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
@@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 28348f2ada98c616241a51aecb70b63e87e6ddbb
-R 9bc31534cba9a5ca27509c106713cf4f
-U mistachkin
-Z 53877e3b824403e5e8a560ad04bec5a4
+P 7789f801d720db5394117e764675cd4bbe6b2da1
+R 3bce36f2564839cff6784053e8b7c283
+U drh
+Z 80f483ee05b71fc1e6bab9b86a396c28
index 37578fbff092341598a71c5577e3fdaa6fd83c19..b80938c565169e50837e78cb8ba34f593014038b 100644 (file)
@@ -1 +1 @@
-7789f801d720db5394117e764675cd4bbe6b2da1
\ No newline at end of file
+2b1884dc14f9a04a04eebb3245fbe0daaff399eb
\ No newline at end of file
index ab657dc7bdc35fa19fe278f7152fc966b49ed855..485b32fd90c8ec65de4108fdf8d14a588c902f90 100644 (file)
@@ -1315,6 +1315,15 @@ static int findInodeInfo(
   return SQLITE_OK;
 }
 
+/*
+** Return TRUE if pFile has been renamed or unlinked since it was first opened.
+*/
+static int fileHasMoved(unixFile *pFile){
+  struct stat buf;
+  return pFile->pInode!=0 &&
+         (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
+}
+
 
 /*
 ** Check a unixFile that is a database.  Verify the following:
@@ -1349,10 +1358,7 @@ static void verifyDbFile(unixFile *pFile){
     pFile->ctrlFlags |= UNIXFILE_WARNED;
     return;
   }
-  if( pFile->pInode!=0
-   && ((rc = osStat(pFile->zPath, &buf))!=0
-       || buf.st_ino!=pFile->pInode->fileId.ino)
-  ){
+  if( fileHasMoved(pFile) ){
     sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
     pFile->ctrlFlags |= UNIXFILE_WARNED;
     return;
@@ -3801,6 +3807,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
       }
       return SQLITE_OK;
     }
+    case SQLITE_FCNTL_HAS_MOVED: {
+      *(int*)pArg = fileHasMoved(pFile);
+      return SQLITE_OK;
+    }
 #if SQLITE_MAX_MMAP_SIZE>0
     case SQLITE_FCNTL_MMAP_SIZE: {
       i64 newLimit = *(i64*)pArg;
index 5803b2927d1ed689cf48dc73dfb59ba8e284d603..297b7bd53485aae02cefc4cbc2fe04d22a3273c3 100644 (file)
@@ -4806,15 +4806,16 @@ static int databaseIsUnmoved(Pager *pPager){
   const int fixedFlags = SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
                          SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN;
   int dc;
-  int x = 0, rc;
+  int bHasMoved = 0;
+  int rc;
 
   if( pPager->tempFile ) return SQLITE_OK;
   if( pPager->dbSize==0 ) return SQLITE_OK;
   assert( pPager->zFilename && pPager->zFilename[0] );
   dc = sqlite3OsDeviceCharacteristics(pPager->fd);
   if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK;
-  rc = sqlite3OsAccess(pPager->pVfs, pPager->zFilename, SQLITE_ACCESS_EXISTS, &x);
-  if( rc==SQLITE_OK && !x ) rc = SQLITE_READONLY_DBMOVED;
+  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+  if( rc==SQLITE_OK && bHasMoved ) rc = SQLITE_READONLY_DBMOVED;
   return rc;
 }
 
index f4692f286a50c78a771106130e8c3adb352ba6fd..fb6fa462ec559e7b4e527bbb8753da7f7400eb6a 100644 (file)
@@ -920,6 +920,12 @@ struct sqlite3_io_methods {
 ** SQLite stack may generate instances of this file control if
 ** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
 **
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
 ** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
@@ -940,6 +946,7 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_TEMPFILENAME           16
 #define SQLITE_FCNTL_MMAP_SIZE              18
 #define SQLITE_FCNTL_TRACE                  19
+#define SQLITE_FCNTL_HAS_MOVED              20
 
 /*
 ** CAPI3REF: Mutex Handle
index e757dbe171e255510dfa9853ff2766c338c56a3f..edfd2660c2b6f52d39e0a949a990fd38459b69b8 100644 (file)
@@ -38,13 +38,24 @@ do_catchsql_test pager4-1.3 {
   UPDATE t1 SET a=537;
 } {1 {attempt to write a readonly database}}
 
+# Creating a different database file with the same name of the original
+# is detected and still leaves the database read-only.
+#
+sqlite3 db2 test.db
+db2 eval {CREATE TABLE t2(x,y,z)}
+do_catchsql_test pager4-1.4 {
+  UPDATE t1 SET a=948;
+} {1 {attempt to write a readonly database}}
+
 # Changing the name back clears the READONLY error
 #
+db2 close
+file delete -force test.db
 file rename test-xyz.db test.db
-do_catchsql_test pager4-1.4 {
+do_catchsql_test pager4-1.5 {
   SELECT * FROM t1;
 } {0 {673 stone philips}}
-do_catchsql_test pager4-1.5 {
+do_catchsql_test pager4-1.6 {
   UPDATE t1 SET a=537;
   SELECT * FROM t1;
 } {0 {537 stone philips}}
@@ -53,12 +64,12 @@ do_catchsql_test pager4-1.5 {
 # journal_mode=MEMORY.
 #
 file rename test.db test-xyz.db
-do_catchsql_test pager4-1.6 {
+do_catchsql_test pager4-1.7 {
   PRAGMA journal_mode=OFF;
   UPDATE t1 SET a=107;
   SELECT * FROM t1;
 } {0 {off 107 stone philips}}
-do_catchsql_test pager4-1.7 {
+do_catchsql_test pager4-1.8 {
   PRAGMA journal_mode=MEMORY;
   UPDATE t1 SET b='magpie';
   SELECT * FROM t1;
@@ -66,15 +77,15 @@ do_catchsql_test pager4-1.7 {
 
 # Any other journal mode gives a READONLY error
 #
-do_catchsql_test pager4-1.8 {
+do_catchsql_test pager4-1.9 {
   PRAGMA journal_mode=DELETE;
   UPDATE t1 SET c='jaguar';
 } {1 {attempt to write a readonly database}}
-do_catchsql_test pager4-1.9 {
+do_catchsql_test pager4-1.10 {
   PRAGMA journal_mode=TRUNCATE;
   UPDATE t1 SET c='jaguar';
 } {1 {attempt to write a readonly database}}
-do_catchsql_test pager4-1.10 {
+do_catchsql_test pager4-1.11 {
   PRAGMA journal_mode=PERSIST;
   UPDATE t1 SET c='jaguar';
 } {1 {attempt to write a readonly database}}