diff options
author | drh <drh@noemail.net> | 2008-07-30 17:28:04 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2008-07-30 17:28:04 +0000 |
commit | 5462624dc4a05fee06396f7f284db4d1a8d57e6b (patch) | |
tree | 9e275b43a69a49dbde2748ce4300984515196f69 /src/os_unix.c | |
parent | da0e768be29110dd4707923a6273cbc34a682e58 (diff) | |
download | sqlite-5462624dc4a05fee06396f7f284db4d1a8d57e6b.tar.gz sqlite-5462624dc4a05fee06396f7f284db4d1a8d57e6b.zip |
When opening a zero-size database on unix, write one byte into the file before
interrogating the inode number. This works around issues with msdos
filesystems mounted on OS-X. Ticket #3260. (CVS 5504)
FossilOrigin-Name: a480a8845fb3b49967de0790b30e6250c824b9be
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 48d2ff176..4874a6437 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -12,7 +12,7 @@ ** ** This file contains code that is specific to Unix systems. ** -** $Id: os_unix.c,v 1.194 2008/07/30 15:27:54 drh Exp $ +** $Id: os_unix.c,v 1.195 2008/07/30 17:28:04 drh Exp $ */ #include "sqliteInt.h" #if SQLITE_OS_UNIX /* This file is used on unix only */ @@ -674,6 +674,24 @@ static int findLockInfo( return SQLITE_IOERR; } + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 ){ + write(fd, "S", 1); + rc = fstat(fd, &statbuf); + if( rc!=0 ){ + return SQLITE_IOERR; + } + } + memset(&key1, 0, sizeof(key1)); key1.dev = statbuf.st_dev; key1.ino = statbuf.st_ino; @@ -1092,6 +1110,16 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ return SQLITE_IOERR_FSTAT; } *pSize = buf.st_size; + + /* When opening a zero-size database, the findLockInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + return SQLITE_OK; } |