SQLite

Check-in [a07c581e88]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When opening the *-shm file for a readonly database, try to open it in read-write mode before falling back to readonly. This is in case some other read/write connection within the same process uses the same file descriptor.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: a07c581e88aa4d9835f6144c0fd5e58ef42f14ac
User & Date: dan 2016-11-17 14:02:50.490
Context
2017-02-17
21:23
Increase the estimated cost of sorting when sorting wide results sets, to account for the extra storage space and I/O required for the external sort. (Leaf check-in: 38298ef923 user: drh tags: apple-increased-sorting-cost)
2016-11-26
20:12
Update test case for opening SHM files read/write on a read-only connection so that they are only attempted on Darwin with SQLITE_ENABLE_PRESIST_WAL. (check-in: d6a7bf80cf user: drh tags: apple-osx)
2016-11-17
14:02
When opening the *-shm file for a readonly database, try to open it in read-write mode before falling back to readonly. This is in case some other read/write connection within the same process uses the same file descriptor. (check-in: a07c581e88 user: dan tags: apple-osx)
2016-11-04
19:09
Merge recent trunk changes, including all the fixes that appeared in version 3.15.1. (check-in: 0e5ffd9123 user: drh tags: apple-osx)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
5044
5045
5046
5047
5048
5049
5050

5051











5052
5053

5054
5055
5056
5057
5058
5059
5060

5061
5062
5063
5064

5065
5066
5067
5068
5069
5070
5071
        rc = SQLITE_NOMEM_BKPT;
        goto shm_open_err;
      }
    }

    if( pInode->bProcessLock==0 ){
      int openFlags = O_RDWR | O_CREAT;

      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0)











#if defined(SQLITE_ENABLE_PERSIST_WAL)&&(SQLITE_ENABLE_LOCKING_STYLE \
    || defined(__APPLE__))

         || (pDbFd->openFlags & O_RDWR) != O_RDWR
#endif
         ){
        openFlags = O_RDONLY;
        pShmNode->isReadonly = 1;
      }
      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));

      if( pShmNode->h<0 ){
        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
        goto shm_open_err;
      }


      /* 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,
      ** the original owner will not be able to connect.
      */
      robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
  







>
|
>
>
>
>
>
>
>
>
>
>
>


>
|
<
|
|


<
>
|



>







5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067

5068
5069
5070
5071

5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
        rc = SQLITE_NOMEM_BKPT;
        goto shm_open_err;
      }
    }

    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) ){
        openFlags = O_RDONLY;
        pShmNode->isReadonly = 1;
      }
      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!=EISDIR && pShmNode->isReadonly==0 
       && (pDbFd->openFlags & O_RDWR)!=O_RDWR

      ){
        fd = robust_open(zShmFilename, O_RDONLY, (sStat.st_mode&0777));
        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,
      ** the original owner will not be able to connect.
      */
      robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
  
Changes to test/walro.test.
299
300
301
302
303
304
305


























































306
307
308
309
  do_test 2.1.4 { set res } {0 {0 2 2}}

  do_test 2.1.5 {
    code1 { db close }
    code1 { tv delete }
  } {}
}



























































forcedelete $shmpath

finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  do_test 2.1.4 { set res } {0 {0 2 2}}

  do_test 2.1.5 {
    code1 { db close }
    code1 { tv delete }
  } {}
}

forcedelete $shmpath

#----------------------------------------------------------------------------

catch {db2 close}
reset_db
do_execsql_test 3.1 {
  CREATE TABLE t1(a, b);
  PRAGMA journal_mode = wal;
  INSERT INTO t1 VALUES(1, 2);
} {wal}
db_save
db close
db_restore

sqlite3 db test.db -readonly 1

do_execsql_test 3.2 { SELECT * FROM t1 } {1 2}
do_catchsql_test 3.3 { 
  INSERT INTO t1 VALUES(3, 4) 
} {1 {attempt to write a readonly database}}

sqlite3 db2 test.db
do_test 3.4 { 
  db2 eval { INSERT INTO t1 VALUES(3, 4) }
} {}
do_execsql_test 3.5 { SELECT * FROM t1 } {1 2 3 4}

db close
db2 close
db_restore
file attributes $shmpath -permissions r--r--r--
sqlite3 db test.db -readonly 1
do_execsql_test 3.6 { SELECT * FROM t1 } {1 2}

db close
db_restore
file attributes $shmpath -permissions r--r--r--
sqlite3 db test.db
do_test 3.7 {
  catchsql { SELECT * FROM t1 } 
} {1 {unable to open database file}}

db close
db_restore
file attributes $shmpath -permissions r--r--r--
sqlite3 db test.db -readonly 1
do_execsql_test 3.8 { SELECT * FROM t1 } {1 2}

sqlite3 db2 test.db
do_test 3.9 { db2 eval { SELECT * FROM t1 } } {1 2}
do_test 3.10 { 
  catchsql { INSERT INTO t1 VALUES(3, 4) } db2 
} {1 {attempt to write a readonly database}}

catch { db close }
catch { db2 close }

forcedelete $shmpath

finish_test