mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Fix a bad interaction between "proxy-locking" and [http://www.sqlite.org/src/vdiff/aa6acfa8caa2ef59b4c16dfe42c4b5644da96905|aa6acfa8ca].
FossilOrigin-Name: 2a5c9e1dbf7f5f4b2081c964450a9305a4516f5b
This commit is contained in:
@@ -3902,7 +3902,7 @@ static int unixOpen(
|
||||
noLock = eType!=SQLITE_OPEN_MAIN_DB;
|
||||
|
||||
#if SQLITE_PREFER_PROXY_LOCKING
|
||||
if( zPath!=NULL && !noLock ){
|
||||
if( zPath!=NULL && !noLock && pVfs->xOpen ){
|
||||
char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
|
||||
int useProxy = 0;
|
||||
|
||||
@@ -4617,33 +4617,43 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
||||
** but also for freeing the memory associated with the file descriptor.
|
||||
*/
|
||||
static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
|
||||
int fd;
|
||||
int dirfd = -1;
|
||||
unixFile *pNew;
|
||||
int flags = SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_vfs dummyVfs;
|
||||
|
||||
fd = open(path, O_RDWR | O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||
if( fd<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
|
||||
pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
|
||||
if( pNew==NULL ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto end_create_proxy;
|
||||
if( !pNew ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
memset(pNew, 0, sizeof(unixFile));
|
||||
|
||||
/* Call unixOpen() to open the proxy file. The flags passed to unixOpen()
|
||||
** suggest that the file being opened is a "main database". This is
|
||||
** necessary as other file types do not necessarily support locking. It
|
||||
** is better to use unixOpen() instead of opening the file directly with
|
||||
** open(), as unixOpen() sets up the various mechanisms required to
|
||||
** make sure a call to close() does not cause the system to discard
|
||||
** POSIX locks prematurely.
|
||||
**
|
||||
** It is important that the xOpen member of the VFS object passed to
|
||||
** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file
|
||||
** for the proxy-file (creating a potential infinite loop).
|
||||
*/
|
||||
dummyVfs.pAppData = (void*)&autolockIoFinder;
|
||||
rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
*ppFile = pNew;
|
||||
return SQLITE_OK;
|
||||
dummyVfs.xOpen = 0;
|
||||
rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags);
|
||||
if( rc==SQLITE_OK && (flags&SQLITE_OPEN_READONLY) ){
|
||||
pNew->pMethod->xClose((sqlite3_file *)pNew);
|
||||
rc = SQLITE_CANTOPEN;
|
||||
}
|
||||
end_create_proxy:
|
||||
close(fd); /* silently leak fd if error, we're already in error */
|
||||
sqlite3_free(pNew);
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
|
||||
*ppFile = pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user