aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2008-07-30 17:28:04 +0000
committerdrh <drh@noemail.net>2008-07-30 17:28:04 +0000
commit5462624dc4a05fee06396f7f284db4d1a8d57e6b (patch)
tree9e275b43a69a49dbde2748ce4300984515196f69 /src/os_unix.c
parentda0e768be29110dd4707923a6273cbc34a682e58 (diff)
downloadsqlite-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.c30
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;
}