aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2009-08-25 05:57:47 +0000
committerdan <dan@noemail.net>2009-08-25 05:57:47 +0000
commit15edd587fd5d460ca0914c764d9ceb3b7d2dc760 (patch)
treec9c1562ac60f1b50ed6e1c1dadd3b626fc5e2bd8 /src/os_unix.c
parent6aa657f76b78c432111ec51e4f6cba195523c7f0 (diff)
downloadsqlite-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.c46
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;
}