Index: third_party/sqlite/sqlite-src-3070603/src/os_unix.c |
diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/sqlite-src-3070603/src/os_unix.c |
similarity index 97% |
copy from third_party/sqlite/src/src/os_unix.c |
copy to third_party/sqlite/sqlite-src-3070603/src/os_unix.c |
index 77ffd8ac0d9a50c0328d03aff3dca52ccd5bb52f..2626ab4d32b9c859bb5ac9af762b45e83b4546a1 100644 |
--- a/third_party/sqlite/src/src/os_unix.c |
+++ b/third_party/sqlite/sqlite-src-3070603/src/os_unix.c |
@@ -204,6 +204,7 @@ struct unixFile { |
sqlite3_io_methods const *pMethod; /* Always the first entry */ |
unixInodeInfo *pInode; /* Info about locks on this inode */ |
int h; /* The file descriptor */ |
+ int dirfd; /* File descriptor for the directory */ |
unsigned char eFileLock; /* The type of lock held on this fd */ |
unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ |
int lastErrno; /* The unix errno from last I/O error */ |
@@ -247,7 +248,6 @@ struct unixFile { |
*/ |
#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ |
#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ |
-#define UNIXFILE_DIRSYNC 0x04 /* Directory sync needed */ |
/* |
** Include code that is common to all os_*.c files |
@@ -281,9 +281,6 @@ struct unixFile { |
#define threadid 0 |
#endif |
-/* Forward reference */ |
-static int openDirectory(const char*, int*); |
- |
/* |
** Many system calls are accessed through pointer-to-functions so that |
** they may be overridden at runtime to facilitate fault injection during |
@@ -380,12 +377,6 @@ static struct unix_syscall { |
#endif |
#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) |
- { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, |
-#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) |
- |
- { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, |
-#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) |
- |
}; /* End of the overrideable system calls */ |
/* |
@@ -1740,6 +1731,10 @@ static int unixUnlock(sqlite3_file *id, int eFileLock){ |
*/ |
static int closeUnixFile(sqlite3_file *id){ |
unixFile *pFile = (unixFile*)id; |
+ if( pFile->dirfd>=0 ){ |
+ robust_close(pFile, pFile->dirfd, __LINE__); |
+ pFile->dirfd=-1; |
+ } |
if( pFile->h>=0 ){ |
robust_close(pFile, pFile->h, __LINE__); |
pFile->h = -1; |
@@ -1747,7 +1742,7 @@ static int closeUnixFile(sqlite3_file *id){ |
#if OS_VXWORKS |
if( pFile->pId ){ |
if( pFile->isDelete ){ |
- osUnlink(pFile->pId->zCanonicalName); |
+ unlink(pFile->pId->zCanonicalName); |
} |
vxworksReleaseFileId(pFile->pId); |
pFile->pId = 0; |
@@ -1994,7 +1989,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { |
/* To fully unlock the database, delete the lock file */ |
assert( eFileLock==NO_LOCK ); |
- if( osUnlink(zLockFile) ){ |
+ if( unlink(zLockFile) ){ |
int rc = 0; |
int tErrno = errno; |
if( ENOENT != tErrno ){ |
@@ -3231,50 +3226,6 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ |
} |
/* |
-** Open a file descriptor to the directory containing file zFilename. |
-** If successful, *pFd is set to the opened file descriptor and |
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM |
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined |
-** value. |
-** |
-** The directory file descriptor is used for only one thing - to |
-** fsync() a directory to make sure file creation and deletion events |
-** are flushed to disk. Such fsyncs are not needed on newer |
-** journaling filesystems, but are required on older filesystems. |
-** |
-** This routine can be overridden using the xSetSysCall interface. |
-** The ability to override this routine was added in support of the |
-** chromium sandbox. Opening a directory is a security risk (we are |
-** told) so making it overrideable allows the chromium sandbox to |
-** replace this routine with a harmless no-op. To make this routine |
-** a no-op, replace it with a stub that returns SQLITE_OK but leaves |
-** *pFd set to a negative number. |
-** |
-** If SQLITE_OK is returned, the caller is responsible for closing |
-** the file descriptor *pFd using close(). |
-*/ |
-static int openDirectory(const char *zFilename, int *pFd){ |
- int ii; |
- int fd = -1; |
- char zDirname[MAX_PATHNAME+1]; |
- |
- sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); |
- for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); |
- if( ii>0 ){ |
- zDirname[ii] = '\0'; |
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); |
- if( fd>=0 ){ |
-#ifdef FD_CLOEXEC |
- osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
-#endif |
- OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); |
- } |
- } |
- *pFd = fd; |
- return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); |
-} |
- |
-/* |
** Make sure all writes to a particular file are committed to disk. |
** |
** If dataOnly==0 then both the file itself and its metadata (file |
@@ -3314,23 +3265,28 @@ static int unixSync(sqlite3_file *id, int flags){ |
pFile->lastErrno = errno; |
return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); |
} |
- |
- /* Also fsync the directory containing the file if the DIRSYNC flag |
- ** is set. This is a one-time occurrance. Many systems (examples: AIX) |
- ** are unable to fsync a directory, so ignore errors on the fsync. |
- */ |
- if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ |
- int dirfd; |
- OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, |
+ if( pFile->dirfd>=0 ){ |
+ OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, |
HAVE_FULLFSYNC, isFullsync)); |
- rc = osOpenDirectory(pFile->zPath, &dirfd); |
- if( rc==SQLITE_OK && dirfd>=0 ){ |
- full_fsync(dirfd, 0, 0); |
- robust_close(pFile, dirfd, __LINE__); |
- }else if( rc==SQLITE_CANTOPEN ){ |
- rc = SQLITE_OK; |
+#ifndef SQLITE_DISABLE_DIRSYNC |
+ /* The directory sync is only attempted if full_fsync is |
+ ** turned off or unavailable. If a full_fsync occurred above, |
+ ** then the directory sync is superfluous. |
+ */ |
+ if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){ |
+ /* |
+ ** We have received multiple reports of fsync() returning |
+ ** errors when applied to directories on certain file systems. |
+ ** A failed directory sync is not a big deal. So it seems |
+ ** better to ignore the error. Ticket #1657 |
+ */ |
+ /* pFile->lastErrno = errno; */ |
+ /* return SQLITE_IOERR; */ |
} |
- pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; |
+#endif |
+ /* Only need to sync once, so close the directory when we are done */ |
+ robust_close(pFile, pFile->dirfd, __LINE__); |
+ pFile->dirfd = -1; |
} |
return rc; |
} |
@@ -4154,7 +4110,7 @@ static int unixShmUnmap( |
assert( pShmNode->nRef>0 ); |
pShmNode->nRef--; |
if( pShmNode->nRef==0 ){ |
- if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); |
+ if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename); |
unixShmPurge(pDbFd); |
} |
unixLeaveMutex(); |
@@ -4462,19 +4418,12 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); |
*/ |
/* |
-** Initializes a unixFile structure with zeros. |
-*/ |
-void initUnixFile(sqlite3_file* file) { |
- memset(file, 0, sizeof(unixFile)); |
-} |
- |
-/* |
** Initialize the contents of the unixFile structure pointed to by pId. |
*/ |
-int fillInUnixFile( |
+static int fillInUnixFile( |
sqlite3_vfs *pVfs, /* Pointer to vfs object */ |
int h, /* Open file descriptor of file being opened */ |
- int syncDir, /* True to sync directory on first sync */ |
+ int dirfd, /* Directory file descriptor */ |
sqlite3_file *pId, /* Write to the unixFile structure here */ |
const char *zFilename, /* Name of the file being opened */ |
int noLock, /* Omit locking if true */ |
@@ -4505,8 +4454,9 @@ int fillInUnixFile( |
OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
pNew->h = h; |
+ pNew->dirfd = dirfd; |
pNew->zPath = zFilename; |
- if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
+ if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ |
pNew->ctrlFlags = UNIXFILE_EXCL; |
}else{ |
pNew->ctrlFlags = 0; |
@@ -4514,9 +4464,6 @@ int fillInUnixFile( |
if( isReadOnly ){ |
pNew->ctrlFlags |= UNIXFILE_RDONLY; |
} |
- if( syncDir ){ |
- pNew->ctrlFlags |= UNIXFILE_DIRSYNC; |
- } |
#if OS_VXWORKS |
pNew->pId = vxworksFindFileId(zFilename); |
@@ -4643,12 +4590,13 @@ int fillInUnixFile( |
if( rc!=SQLITE_OK ){ |
if( h>=0 ) robust_close(pNew, h, __LINE__); |
h = -1; |
- osUnlink(zFilename); |
+ unlink(zFilename); |
isDelete = 0; |
} |
pNew->isDelete = isDelete; |
#endif |
if( rc!=SQLITE_OK ){ |
+ if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__); |
if( h>=0 ) robust_close(pNew, h, __LINE__); |
}else{ |
pNew->pMethod = pLockingStyle; |
@@ -4658,6 +4606,37 @@ int fillInUnixFile( |
} |
/* |
+** Open a file descriptor to the directory containing file zFilename. |
+** If successful, *pFd is set to the opened file descriptor and |
+** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM |
+** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined |
+** value. |
+** |
+** If SQLITE_OK is returned, the caller is responsible for closing |
+** the file descriptor *pFd using close(). |
+*/ |
+static int openDirectory(const char *zFilename, int *pFd){ |
+ int ii; |
+ int fd = -1; |
+ char zDirname[MAX_PATHNAME+1]; |
+ |
+ sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); |
+ for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); |
+ if( ii>0 ){ |
+ zDirname[ii] = '\0'; |
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); |
+ if( fd>=0 ){ |
+#ifdef FD_CLOEXEC |
+ osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
+#endif |
+ OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); |
+ } |
+ } |
+ *pFd = fd; |
+ return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); |
+} |
+ |
+/* |
** Return the name of a directory in which to put temporary files. |
** If no suitable temporary file directory can be found, return NULL. |
*/ |
@@ -4771,7 +4750,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ |
** |
** Even if a subsequent open() call does succeed, the consequences of |
** not searching for a resusable file descriptor are not dire. */ |
- if( 0==osStat(zPath, &sStat) ){ |
+ if( 0==stat(zPath, &sStat) ){ |
unixInodeInfo *pInode; |
unixEnterMutex(); |
@@ -4841,7 +4820,7 @@ static int findCreateFileMode( |
memcpy(zDb, zPath, nDb); |
zDb[nDb] = '\0'; |
- if( 0==osStat(zDb, &sStat) ){ |
+ if( 0==stat(zDb, &sStat) ){ |
*pMode = sStat.st_mode & 0777; |
}else{ |
rc = SQLITE_IOERR_FSTAT; |
@@ -4855,73 +4834,6 @@ static int findCreateFileMode( |
} |
/* |
-** Initializes a unixFile structure with zeros. |
-*/ |
-void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { |
- memset(file, 0, sizeof(unixFile)); |
-} |
- |
-int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, |
- int fd, |
- int dirfd, |
- sqlite3_file* file, |
- const char* fileName, |
- int noLock, |
- int isDelete) { |
- return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete, 0); |
-} |
- |
-/* |
-** Search for an unused file descriptor that was opened on the database file. |
-** If a suitable file descriptor if found, then it is stored in *fd; otherwise, |
-** *fd is not modified. |
-** |
-** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot |
-** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. |
-*/ |
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, |
- const char* fileName, |
- int flags, |
- int* fd) { |
- unixFile* unixSQLite3File = (unixFile*)file; |
- int fileType = flags & 0xFFFFFF00; |
- if (fileType == SQLITE_OPEN_MAIN_DB) { |
- UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); |
- if (unusedFd) { |
- *fd = unusedFd->fd; |
- } else { |
- unusedFd = sqlite3_malloc(sizeof(*unusedFd)); |
- if (!unusedFd) { |
- return SQLITE_NOMEM; |
- } |
- } |
- unixSQLite3File->pUnused = unusedFd; |
- } |
- return SQLITE_OK; |
-} |
- |
-/* |
-** Marks 'fd' as the unused file descriptor for 'pFile'. |
-*/ |
-void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, |
- int fd, |
- int flags) { |
- unixFile* unixSQLite3File = (unixFile*)file; |
- if (unixSQLite3File->pUnused) { |
- unixSQLite3File->pUnused->fd = fd; |
- unixSQLite3File->pUnused->flags = flags; |
- } |
-} |
- |
-/* |
-** Destroys pFile's field that keeps track of the unused file descriptor. |
-*/ |
-void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { |
- unixFile* unixSQLite3File = (unixFile*)file; |
- sqlite3_free(unixSQLite3File->pUnused); |
-} |
- |
-/* |
** Open the file zPath. |
** |
** Previously, the SQLite OS layer used three functions in place of this |
@@ -4952,6 +4864,7 @@ static int unixOpen( |
){ |
unixFile *p = (unixFile *)pFile; |
int fd = -1; /* File descriptor returned by open() */ |
+ int dirfd = -1; /* Directory file descriptor */ |
int openFlags = 0; /* Flags to pass to open() */ |
int eType = flags&0xFFFFFF00; /* Type of file to open */ |
int noLock; /* True to omit locking primitives */ |
@@ -4970,7 +4883,7 @@ static int unixOpen( |
** a file-descriptor on the directory too. The first time unixSync() |
** is called the directory file descriptor will be fsync()ed and close()d. |
*/ |
- int syncDir = (isCreate && ( |
+ int isOpenDirectory = (isCreate && ( |
eType==SQLITE_OPEN_MASTER_JOURNAL |
|| eType==SQLITE_OPEN_MAIN_JOURNAL |
|| eType==SQLITE_OPEN_WAL |
@@ -5008,16 +4921,23 @@ static int unixOpen( |
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL |
); |
- chromium_sqlite3_initialize_unix_sqlite3_file(pFile); |
+ memset(p, 0, sizeof(unixFile)); |
if( eType==SQLITE_OPEN_MAIN_DB ){ |
- rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); |
- if( rc!=SQLITE_OK ){ |
- return rc; |
+ UnixUnusedFd *pUnused; |
+ pUnused = findReusableFd(zName, flags); |
+ if( pUnused ){ |
+ fd = pUnused->fd; |
+ }else{ |
+ pUnused = sqlite3_malloc(sizeof(*pUnused)); |
+ if( !pUnused ){ |
+ return SQLITE_NOMEM; |
+ } |
} |
+ p->pUnused = pUnused; |
}else if( !zName ){ |
/* If zName is NULL, the upper layer is requesting a temp file. */ |
- assert(isDelete && !syncDir); |
+ assert(isDelete && !isOpenDirectory); |
rc = unixGetTempname(MAX_PATHNAME+1, zTmpname); |
if( rc!=SQLITE_OK ){ |
return rc; |
@@ -5064,13 +4984,16 @@ static int unixOpen( |
*pOutFlags = flags; |
} |
- chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); |
+ if( p->pUnused ){ |
+ p->pUnused->fd = fd; |
+ p->pUnused->flags = flags; |
+ } |
if( isDelete ){ |
#if OS_VXWORKS |
zPath = zName; |
#else |
- osUnlink(zName); |
+ unlink(zName); |
#endif |
} |
#if SQLITE_ENABLE_LOCKING_STYLE |
@@ -5079,6 +5002,19 @@ static int unixOpen( |
} |
#endif |
+ if( isOpenDirectory ){ |
+ rc = openDirectory(zPath, &dirfd); |
+ if( rc!=SQLITE_OK ){ |
+ /* It is safe to close fd at this point, because it is guaranteed not |
+ ** to be open on a database file. If it were open on a database file, |
+ ** it would not be safe to close as this would release any locks held |
+ ** on the file by this process. */ |
+ assert( eType!=SQLITE_OPEN_MAIN_DB ); |
+ robust_close(p, fd, __LINE__); |
+ goto open_finished; |
+ } |
+ } |
+ |
#ifdef FD_CLOEXEC |
osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
#endif |
@@ -5090,6 +5026,7 @@ static int unixOpen( |
struct statfs fsInfo; |
if( fstatfs(fd, &fsInfo) == -1 ){ |
((unixFile*)pFile)->lastErrno = errno; |
+ if( dirfd>=0 ) robust_close(p, dirfd, __LINE__); |
robust_close(p, fd, __LINE__); |
return SQLITE_IOERR_ACCESS; |
} |
@@ -5121,6 +5058,9 @@ static int unixOpen( |
** not while other file descriptors opened by the same process on |
** the same file are working. */ |
p->lastErrno = errno; |
+ if( dirfd>=0 ){ |
+ robust_close(p, dirfd, __LINE__); |
+ } |
robust_close(p, fd, __LINE__); |
rc = SQLITE_IOERR_ACCESS; |
goto open_finished; |
@@ -5128,7 +5068,7 @@ static int unixOpen( |
useProxy = !(fsInfo.f_flags&MNT_LOCAL); |
} |
if( useProxy ){ |
- rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, |
+ rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, |
isDelete, isReadonly); |
if( rc==SQLITE_OK ){ |
rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); |
@@ -5146,11 +5086,11 @@ static int unixOpen( |
} |
#endif |
- rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock, |
+ rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, |
isDelete, isReadonly); |
open_finished: |
if( rc!=SQLITE_OK ){ |
- chromium_sqlite3_destroy_reusable_file_handle(pFile); |
+ sqlite3_free(p->pUnused); |
} |
return rc; |
} |
@@ -5168,13 +5108,13 @@ static int unixDelete( |
int rc = SQLITE_OK; |
UNUSED_PARAMETER(NotUsed); |
SimulateIOError(return SQLITE_IOERR_DELETE); |
- if( osUnlink(zPath)==(-1) && errno!=ENOENT ){ |
+ if( unlink(zPath)==(-1) && errno!=ENOENT ){ |
return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); |
} |
#ifndef SQLITE_DISABLE_DIRSYNC |
if( dirSync ){ |
int fd; |
- rc = osOpenDirectory(zPath, &fd); |
+ rc = openDirectory(zPath, &fd); |
if( rc==SQLITE_OK ){ |
#if OS_VXWORKS |
if( fsync(fd)==-1 ) |
@@ -5185,8 +5125,6 @@ static int unixDelete( |
rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); |
} |
robust_close(0, fd, __LINE__); |
- }else if( rc==SQLITE_CANTOPEN ){ |
- rc = SQLITE_OK; |
} |
} |
#endif |
@@ -5229,7 +5167,7 @@ static int unixAccess( |
*pResOut = (osAccess(zPath, amode)==0); |
if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ |
struct stat buf; |
- if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ |
+ if( 0==stat(zPath, &buf) && buf.st_size==0 ){ |
*pResOut = 0; |
} |
} |
@@ -5748,6 +5686,7 @@ static int proxyCreateUnixFile( |
int islockfile /* if non zero missing dirs will be created */ |
) { |
int fd = -1; |
+ int dirfd = -1; |
unixFile *pNew; |
int rc = SQLITE_OK; |
int openFlags = O_RDWR | O_CREAT; |
@@ -5812,7 +5751,7 @@ static int proxyCreateUnixFile( |
pUnused->flags = openFlags; |
pNew->pUnused = pUnused; |
- rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0); |
+ rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0); |
if( rc==SQLITE_OK ){ |
*ppFile = pNew; |
return SQLITE_OK; |
@@ -5926,7 +5865,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ |
end_breaklock: |
if( rc ){ |
if( fd>=0 ){ |
- osUnlink(tPath); |
+ unlink(tPath); |
robust_close(pFile, fd, __LINE__); |
} |
fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); |
@@ -6749,7 +6688,7 @@ int sqlite3_os_init(void){ |
/* Double-check that the aSyscall[] array has been constructed |
** correctly. See ticket [bb3a86e890c8e96ab] */ |
- assert( ArraySize(aSyscall)==18 ); |
+ assert( ArraySize(aSyscall)==16 ); |
/* Register all VFSes defined in the aVfs[] array */ |
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |