diff options
author | dan <dan@noemail.net> | 2009-08-25 05:57:47 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2009-08-25 05:57:47 +0000 |
commit | 15edd587fd5d460ca0914c764d9ceb3b7d2dc760 (patch) | |
tree | c9c1562ac60f1b50ed6e1c1dadd3b626fc5e2bd8 /src/os_unix.c | |
parent | 6aa657f76b78c432111ec51e4f6cba195523c7f0 (diff) | |
download | sqlite-15edd587fd5d460ca0914c764d9ceb3b7d2dc760.tar.gz sqlite-15edd587fd5d460ca0914c764d9ceb3b7d2dc760.zip |
Fix a bad interaction between "proxy-locking" and [http://www.sqlite.org/src/vdiff/aa6acfa8caa2ef59b4c16dfe42c4b5644da96905|aa6acfa8ca].
FossilOrigin-Name: 2a5c9e1dbf7f5f4b2081c964450a9305a4516f5b
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 65259a756..b88cc7a8b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -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; } |