aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btree.c10
-rw-r--r--src/os.c2
-rw-r--r--src/os_unix.c42
-rw-r--r--src/os_win.c12
-rw-r--r--src/pager.c15
-rw-r--r--src/sqlite.h.in2
-rw-r--r--src/test_demovfs.c6
-rw-r--r--src/test_vfs.c1
8 files changed, 36 insertions, 54 deletions
diff --git a/src/btree.c b/src/btree.c
index 57634f69b..d0eed5dd4 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -2403,9 +2403,13 @@ int sqlite3BtreeOpen(
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return rc;
+ if( rc==SQLITE_OK_SYMLINK ){
+ rc = SQLITE_OK;
+ }else{
+ sqlite3_free(zFullPathname);
+ sqlite3_free(p);
+ return rc;
+ }
}
}
#if SQLITE_THREADSAFE
diff --git a/src/os.c b/src/os.c
index b9ad29d4f..b729e95e6 100644
--- a/src/os.c
+++ b/src/os.c
@@ -215,7 +215,7 @@ int sqlite3OsOpen(
** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
** reaching the VFS. */
- rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
+ rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
assert( rc==SQLITE_OK || pFile->pMethods==0 );
return rc;
}
diff --git a/src/os_unix.c b/src/os_unix.c
index 7217a5d5f..18f2afcb6 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3685,7 +3685,7 @@ static int openDirectory(const char *zFilename, int *pFd){
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
@@ -4576,10 +4576,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
+ (sStat.st_mode&0777));
}
if( pShmNode->hShm<0 ){
- pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
+ (sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
@@ -5929,7 +5931,7 @@ static int unixOpen(
unixFile *p = (unixFile *)pFile;
int fd = -1; /* File descriptor returned by open() */
int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int eType = flags&0x0FFF00; /* Type of file to open */
int noLock; /* True to omit locking primitives */
int rc = SQLITE_OK; /* Function Return Code */
int ctrlFlags = 0; /* UNIXFILE_* flags */
@@ -6039,7 +6041,7 @@ static int unixOpen(
if( isReadWrite ) openFlags |= O_RDWR;
if( isCreate ) openFlags |= O_CREAT;
if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY);
+ openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW);
if( fd<0 ){
mode_t openMode; /* Permissions to create file with */
@@ -6251,25 +6253,15 @@ static int unixAccess(
SimulateIOError( return SQLITE_IOERR_ACCESS; );
assert( pResOut!=0 );
- /* The spec says there are four possible values for flags. But the
- ** SQLITE_ACCESS_READ flag is never used */
- assert( flags==SQLITE_ACCESS_EXISTS
- || flags==SQLITE_ACCESS_READWRITE
- || flags==SQLITE_ACCESS_SYMLINK );
+ /* The spec says there are three possible values for flags. But only
+ ** two of them are actually used */
+ assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
if( flags==SQLITE_ACCESS_EXISTS ){
struct stat buf;
*pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
- }else if( flags==SQLITE_ACCESS_READWRITE ){
- *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}else{
-#if !defined(HAVE_LSTAT)
- *pResOut = 0;
-#else
- struct stat buf;
- *pResOut = (0==osLstat(zPath, &buf) && S_ISLNK(buf.st_mode));
-#endif
- assert( flags==SQLITE_ACCESS_SYMLINK );
+ *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
return SQLITE_OK;
}
@@ -6321,7 +6313,7 @@ static int unixFullPathname(
#else
int rc = SQLITE_OK;
int nByte;
- int nLink = 1; /* Number of symbolic links followed so far */
+ int nLink = 0; /* Number of symbolic links followed so far */
const char *zIn = zPath; /* Input path for each iteration of loop */
char *zDel = 0;
@@ -6350,10 +6342,11 @@ static int unixFullPathname(
}
if( bLink ){
+ nLink++;
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
- }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
+ }else if( nLink>=SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
@@ -6389,6 +6382,7 @@ static int unixFullPathname(
}while( rc==SQLITE_OK );
sqlite3_free(zDel);
+ if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
return rc;
#endif /* HAVE_READLINK && HAVE_LSTAT */
}
@@ -6874,7 +6868,7 @@ static int proxyCreateUnixFile(
int fd = -1;
unixFile *pNew;
int rc = SQLITE_OK;
- int openFlags = O_RDWR | O_CREAT;
+ int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW;
sqlite3_vfs dummyVfs;
int terrno = 0;
UnixUnusedFd *pUnused = NULL;
@@ -6904,7 +6898,7 @@ static int proxyCreateUnixFile(
}
}
if( fd<0 ){
- openFlags = O_RDONLY;
+ openFlags = O_RDONLY | O_NOFOLLOW;
fd = robust_open(path, openFlags, 0);
terrno = errno;
}
@@ -7030,7 +7024,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
goto end_breaklock;
}
/* write it out to the temporary break file */
- fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
+ fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW), 0);
if( fd<0 ){
sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
goto end_breaklock;
diff --git a/src/os_win.c b/src/os_win.c
index 698d6556c..32758ab76 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -81,14 +81,6 @@
#endif
/*
-** This constant is needed by the winAccess function; therefore, define
-** it when it is missing from the SDK header files.
-*/
-#ifndef FILE_ATTRIBUTE_REPARSE_POINT
-# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
-#endif
-
-/*
** Check to see if the GetVersionEx[AW] functions are deprecated on the
** target system. GetVersionEx was first deprecated in Win8.1.
*/
@@ -5480,10 +5472,6 @@ static int winAccess(
rc = attr!=INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_READONLY)==0;
break;
- case SQLITE_ACCESS_SYMLINK:
- rc = attr!=INVALID_FILE_ATTRIBUTES &&
- (attr & FILE_ATTRIBUTE_REPARSE_POINT)!=0;
- break;
default:
assert(!"Invalid flags argument");
}
diff --git a/src/pager.c b/src/pager.c
index 67e757640..9d4922c4a 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -4790,12 +4790,6 @@ int sqlite3PagerOpen(
*/
if( zFilename && zFilename[0] ){
const char *z;
- if( (vfsFlags & SQLITE_OPEN_NOFOLLOW)!=0 ){
- int isLink = 0;
- int rc = sqlite3OsAccess(pVfs, zFilename, SQLITE_ACCESS_SYMLINK, &isLink);
- if( rc==SQLITE_OK && isLink ) rc = SQLITE_CANTOPEN_SYMLINK;
- if( rc ) return rc;
- }
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
@@ -4803,6 +4797,15 @@ int sqlite3PagerOpen(
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_OK_SYMLINK ){
+ if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){
+ rc = SQLITE_CANTOPEN_SYMLINK;
+ }else{
+ rc = SQLITE_OK;
+ }
+ }
+ }
nPathname = sqlite3Strlen30(zPathname);
z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
while( *z ){
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 8373f5c7f..53fb22651 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -541,6 +541,7 @@ int sqlite3_exec(
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -1408,7 +1409,6 @@ struct sqlite3_vfs {
#define SQLITE_ACCESS_EXISTS 0
#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */
#define SQLITE_ACCESS_READ 2 /* Unused */
-#define SQLITE_ACCESS_SYMLINK 3 /* Test if file is symbolic link */
/*
** CAPI3REF: Flags for the xShmLock VFS method
diff --git a/src/test_demovfs.c b/src/test_demovfs.c
index baf14b10b..eaba20873 100644
--- a/src/test_demovfs.c
+++ b/src/test_demovfs.c
@@ -508,14 +508,8 @@ static int demoAccess(
assert( flags==SQLITE_ACCESS_EXISTS /* access(zPath, F_OK) */
|| flags==SQLITE_ACCESS_READ /* access(zPath, R_OK) */
|| flags==SQLITE_ACCESS_READWRITE /* access(zPath, R_OK|W_OK) */
- || flags==SQLITE_ACCESS_SYMLINK /* Always false */
);
- if( flags==SQLITE_ACCESS_SYMLINK ){
- /* For this demo implementation, assume that symlinks do not exist. */
- *pResOut = 0;
- return SQLITE_OK;
- }
if( flags==SQLITE_ACCESS_READWRITE ) eAccess = R_OK|W_OK;
if( flags==SQLITE_ACCESS_READ ) eAccess = R_OK;
diff --git a/src/test_vfs.c b/src/test_vfs.c
index f1ed8d051..9d753896e 100644
--- a/src/test_vfs.c
+++ b/src/test_vfs.c
@@ -732,7 +732,6 @@ static int tvfsAccess(
if( flags==SQLITE_ACCESS_EXISTS ) zArg = "SQLITE_ACCESS_EXISTS";
if( flags==SQLITE_ACCESS_READWRITE ) zArg = "SQLITE_ACCESS_READWRITE";
if( flags==SQLITE_ACCESS_READ ) zArg = "SQLITE_ACCESS_READ";
- if( flags==SQLITE_ACCESS_SYMLINK ) zArg = "SQLITE_ACCESS_SYMLINK";
tvfsExecTcl(p, "xAccess",
Tcl_NewStringObj(zPath, -1), Tcl_NewStringObj(zArg, -1), 0, 0
);