1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

On unix, if a file is opened via a symlink, create, read and write journal and wal files based on the name of the actual db file, not the symlink.

FossilOrigin-Name: c7c8105099c0412ac6c605f98987092c10bde57c
This commit is contained in:
dan
2015-10-31 17:58:33 +00:00
parent 6a75c8ad94
commit 245fdc60d6
6 changed files with 183 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
C Add\smutex\soperations\sto\stest\scode\sin\stest3.c\sto\savoid\striggering\sassert()\sfailures\sin\scertain\sconfigurations. C On\sunix,\sif\sa\sfile\sis\sopened\svia\sa\ssymlink,\screate,\sread\sand\swrite\sjournal\sand\swal\sfiles\sbased\son\sthe\sname\sof\sthe\sactual\sdb\sfile,\snot\sthe\ssymlink.
D 2015-10-30T20:54:25.598 D 2015-10-31T17:58:33.378
F Makefile.in 4469ed8b02a9934fea9503d791165367d19db2f7 F Makefile.in 4469ed8b02a9934fea9503d791165367d19db2f7
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4
@@ -324,7 +324,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_unix.c cf72e06e15839ebe7121e01d3eebf256c039b0ca
F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 9c1eec0d88133484b165fa0b5284a411c24b964c F src/pager.c 9c1eec0d88133484b165fa0b5284a411c24b964c
@@ -913,7 +913,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test 14fec2796c2b6fe431c7823750e8a18a761176d7 F test/oserror.test 361346396ae18462c7393c1ac5c3f17237bd89b2
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799 F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
@@ -1046,8 +1046,9 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/tabfunc01.test 03c4ad422c6ab596cff6dcaf86dd061a9f039525 F test/tabfunc01.test 03c4ad422c6ab596cff6dcaf86dd061a9f039525
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
@@ -1397,7 +1398,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 7565b046ff939e8310631397a4526fbd98b99aaf P 9f19420b0a79dff65fc3a9d548f4b3fc4955f9f9
R 614298574df997c982bceb820bb362b3 R 6c3cb8b317a5bfe5a7c51bf7e4e6022e
T *branch * follow-symlinks
T *sym-follow-symlinks *
T -sym-trunk *
U dan U dan
Z ee268c45e17adbdf740dc7b91893f898 Z 9a079ec9742e185ced0424071f7f7c65

View File

@@ -1 +1 @@
9f19420b0a79dff65fc3a9d548f4b3fc4955f9f9 c7c8105099c0412ac6c605f98987092c10bde57c

View File

@@ -464,6 +464,9 @@ static struct unix_syscall {
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) #define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
{ "readlink", (sqlite3_syscall_ptr)readlink, 0 },
#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[25].pCurrent)
#endif #endif
}; /* End of the overrideable system calls */ }; /* End of the overrideable system calls */
@@ -6026,6 +6029,7 @@ static int unixFullPathname(
int nOut, /* Size of output buffer in bytes */ int nOut, /* Size of output buffer in bytes */
char *zOut /* Output buffer */ char *zOut /* Output buffer */
){ ){
int nByte;
/* It's odd to simulate an io-error here, but really this is just /* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this ** using the io-error infrastructure to test that SQLite handles this
@@ -6037,17 +6041,53 @@ static int unixFullPathname(
assert( pVfs->mxPathname==MAX_PATHNAME ); assert( pVfs->mxPathname==MAX_PATHNAME );
UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(pVfs);
zOut[nOut-1] = '\0'; /* Attempt to resolve the path as if it were a symbolic link. If it is
if( zPath[0]=='/' ){ ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
sqlite3_snprintf(nOut, zOut, "%s", zPath); ** the identified file is not a symbolic link or does not exist, then
** zPath is copied directly into zOut. Either way, nByte is left set to
** the size of the string copied into zOut[] in bytes. */
nByte = osReadlink(zPath, zOut, nOut-1);
if( nByte<0 ){
if( errno!=EINVAL && errno!=ENOENT ){
return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
}
zOut[nOut-1] = '\0';
sqlite3_snprintf(nOut-1, zOut, "%s", zPath);
nByte = sqlite3Strlen30(zOut);
}else{ }else{
zOut[nByte] = '\0';
}
/* If buffer zOut[] now contains an absolute path there is nothing more
** to do. If it contains a relative path, do the following:
**
** * move the relative path string so that it is at the end of th
** zOut[] buffer.
** * Call getcwd() to read the path of the current working directory
** into the start of the zOut[] buffer.
** * Append a '/' character to the cwd string and move the
** relative path back within the buffer so that it immediately
** follows the '/'.
**
** This code is written so that if the combination of the CWD and relative
** path are larger than the allocated size of zOut[] the CWD is silently
** truncated to make it fit. This is Ok, as SQLite refuses to open any
** file for which this function returns a full path larger than (nOut-8)
** bytes in size. */
if( zOut[0]!='/' ){
int nCwd; int nCwd;
if( osGetcwd(zOut, nOut-1)==0 ){ int nRem = nOut-nByte-1;
memmove(&zOut[nRem], zOut, nByte+1);
zOut[nRem-1] = '\0';
if( osGetcwd(zOut, nRem-1)==0 ){
return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
} }
nCwd = (int)strlen(zOut); nCwd = sqlite3Strlen30(zOut);
sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); assert( nCwd<=nRem-1 );
zOut[nCwd] = '/';
memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
} }
return SQLITE_OK; return SQLITE_OK;
} }
@@ -7542,7 +7582,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed /* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */ ** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==25 ); assert( ArraySize(aSyscall)==26 );
/* Register all VFSes defined in the aVfs[] array */ /* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){

View File

@@ -93,7 +93,9 @@ do_test 1.4.1 {
list [catch { sqlite3 dbh /root/test.db } msg] $msg list [catch { sqlite3 dbh /root/test.db } msg] $msg
} {1 {unable to open database file}} } {1 {unable to open database file}}
do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(\d+\) open\(.*test.db\) - } do_re_test 1.4.2 {
lindex $::log 0
} {^os_unix.c:\d*: \(\d+\) (open|readlink)\(.*test.db\) - }
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# Tests oserror-1.* test failures in the unlink() system call. # Tests oserror-1.* test failures in the unlink() system call.

119
test/symlink.test Normal file
View File

@@ -0,0 +1,119 @@
# 2015 October 31
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing that SQLite can follow symbolic links.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix symlink
# This only runs on unix.
if {$::tcl_platform(platform)!="unix"} {
finish_test
return
}
# Ensure that test.db has been created.
#
do_execsql_test 1.0 {
CREATE TABLE t1(x, y);
}
# Test that SQLite follows symlinks when opening files.
#
forcedelete test.db2
do_test 1.1 {
file link test.db2 test.db
sqlite3 db2 test.db2
sqlite3_db_filename db2 main
} [file join [pwd] test.db]
# Test that if the symlink points to a file that does not exists, it is
# created when it is opened.
#
do_test 1.2.1 {
db2 close
db close
forcedelete test.db
file exists test.db
} 0
do_test 1.2.2 {
sqlite3 db2 test.db2
file exists test.db
} 1
do_test 1.2.3 {
sqlite3_db_filename db2 main
} [file join [pwd] test.db]
db2 close
# Test that a loop of symlinks cannot be opened.
#
do_test 1.3 {
forcedelete test.db
# Note: Tcl [file link] command is too smart to create loops of symlinks.
exec ln -s test.db2 test.db
list [catch { sqlite3 db test.db } msg] $msg
} {1 {unable to open database file}}
# Test that overly large paths cannot be opened.
#
do_test 1.4 {
set name "test.db[string repeat x 502]"
list [catch { sqlite3 db $name } msg] $msg
} {1 {unable to open database file}}
do_test 1.5 {
set r [expr 510 - [string length test.db] - [string length [pwd]]]
set name "test.db[string repeat x $r]"
list [catch { sqlite3 db $name } msg] $msg
} {1 {unable to open database file}}
#-------------------------------------------------------------------------
# Test that journal and wal files are created next to the real file,
# not the symlink.
#
do_test 2.0 {
catch { db close }
catch { db2 close }
forcedelete test.db test.db2
sqlite3 db test.db
execsql { CREATE TABLE t1(x) }
file link test.db2 test.db
sqlite3 db2 test.db2
file exists test.db-journal
} 0
do_test 2.1 {
execsql {
BEGIN;
INSERT INTO t1 VALUES(1);
} db2
file exists test.db-journal
} 1
do_test 2.2 {
file exists test.db2-journal
} 0
do_test 2.3 {
execsql {
COMMIT;
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(2);
} db2
file exists test.db-wal
} 1
do_test 2.4 {
file exists test.db2-wal
} 0
do_execsql_test 2.5 {
SELECT * FROM t1;
} {1 2}
finish_test

View File

@@ -61,7 +61,7 @@ foreach s {
fcntl read pread write pwrite fchmod fallocate fcntl read pread write pwrite fchmod fallocate
pread64 pwrite64 unlink openDirectory mkdir rmdir pread64 pwrite64 unlink openDirectory mkdir rmdir
statvfs fchown umask mmap munmap mremap statvfs fchown umask mmap munmap mremap
getpagesize getpagesize readlink
} { } {
if {[test_syscall exists $s]} {lappend syscall_list $s} if {[test_syscall exists $s]} {lappend syscall_list $s}
} }