Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Unified Diff: third_party/sqlite/system-sqlite.patch

Issue 7629003: Backport more SQLite changes to enable system-sqlite experiments. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/src/test/syscall.test ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/system-sqlite.patch
diff --git a/third_party/sqlite/system-sqlite.patch b/third_party/sqlite/system-sqlite.patch
index f61f019e618484e10773eba30cae3a8401619fd6..4760ceaef49f76853c17376429ef37da2bc2dfb3 100644
--- a/third_party/sqlite/system-sqlite.patch
+++ b/third_party/sqlite/system-sqlite.patch
@@ -1,48 +1,880 @@
-This is a backport of http://sqlite.org/src/ci/9109128cb5,
-which is needed for experiments with using unpatched sqlite.
+This is a backport of the following sqlite changes:
+
+1. http://sqlite.org/src/ci/9109128cb5
+2. http://sqlite.org/src/ci/713b1b7dc1
+3. http://sqlite.org/src/ci/8d1b5c3ac0
+4. http://sqlite.org/src/ci/6b236069e1
+5. http://sqlite.org/src/ci/880b51150a
+
+which are needed for experiments with using unpatched sqlite.
If you hit a merge conflict on this file it is most likely
-that you've upgraded to version of sqlite that includes this patch.
-Index: src/os_unix.c
-===================================================================
---- src/os_unix.c
-+++ src/os_unix.c
-@@ -4787,11 +4787,11 @@
- ** ignored and -1 is returned. The caller will try to open a new file
- ** descriptor on the same path, fail, and return an error to SQLite.
- **
- ** Even if a subsequent open() call does succeed, the consequences of
- ** not searching for a resusable file descriptor are not dire. */
-- if( 0==stat(zPath, &sStat) ){
-+ if( 0==osStat(zPath, &sStat) ){
- unixInodeInfo *pInode;
-
- unixEnterMutex();
- pInode = inodeList;
- while( pInode && (pInode->fileId.dev!=sStat.st_dev
-@@ -4863,11 +4863,11 @@
- while( nDb>0 && zPath[nDb]!='-' ) nDb--;
- if( nDb==0 ) return SQLITE_OK;
- memcpy(zDb, zPath, nDb);
- zDb[nDb] = '\0';
-
-- if( 0==stat(zDb, &sStat) ){
-+ if( 0==osStat(zDb, &sStat) ){
- *pMode = sStat.st_mode & 0777;
- }else{
- rc = SQLITE_IOERR_FSTAT;
- }
- }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
-@@ -5208,11 +5208,11 @@
- assert(!"Invalid flags argument");
- }
- *pResOut = (osAccess(zPath, amode)==0);
- if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
- struct stat buf;
-- if( 0==stat(zPath, &buf) && buf.st_size==0 ){
-+ if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
- *pResOut = 0;
- }
- }
- return SQLITE_OK;
+that you've upgraded to version of sqlite that includes those patches.
+diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
+index 3e794a9..73ff15f 100644
+--- a/third_party/sqlite/amalgamation/sqlite3.c
++++ b/third_party/sqlite/amalgamation/sqlite3.c
+@@ -24144,7 +24144,6 @@ 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 */
+@@ -24188,6 +24187,7 @@ 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
+@@ -24426,6 +24426,9 @@ SQLITE_API int sqlite3_open_file_count = 0;
+ #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
+@@ -24522,6 +24525,12 @@ 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 */
+
+ /*
+@@ -25876,10 +25885,6 @@ 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;
+@@ -25887,7 +25892,7 @@ static int closeUnixFile(sqlite3_file *id){
+ #if OS_VXWORKS
+ if( pFile->pId ){
+ if( pFile->isDelete ){
+- unlink(pFile->pId->zCanonicalName);
++ osUnlink(pFile->pId->zCanonicalName);
+ }
+ vxworksReleaseFileId(pFile->pId);
+ pFile->pId = 0;
+@@ -26134,7 +26139,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
+
+ /* To fully unlock the database, delete the lock file */
+ assert( eFileLock==NO_LOCK );
+- if( unlink(zLockFile) ){
++ if( osUnlink(zLockFile) ){
+ int rc = 0;
+ int tErrno = errno;
+ if( ENOENT != tErrno ){
+@@ -27371,6 +27376,50 @@ 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
+@@ -27410,28 +27459,21 @@ static int unixSync(sqlite3_file *id, int flags){
+ pFile->lastErrno = errno;
+ return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
+ }
+- if( pFile->dirfd>=0 ){
+- OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
++
++ /* 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,
+ HAVE_FULLFSYNC, isFullsync));
+-#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; */
++ rc = osOpenDirectory(pFile->zPath, &dirfd);
++ if( rc==SQLITE_OK && dirfd>=0 ){
++ full_fsync(dirfd, 0, 0);
++ robust_close(pFile, dirfd, __LINE__);
+ }
+-#endif
+- /* Only need to sync once, so close the directory when we are done */
+- robust_close(pFile, pFile->dirfd, __LINE__);
+- pFile->dirfd = -1;
++ pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
+ }
+ return rc;
+ }
+@@ -28255,7 +28297,7 @@ static int unixShmUnmap(
+ assert( pShmNode->nRef>0 );
+ pShmNode->nRef--;
+ if( pShmNode->nRef==0 ){
+- if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename);
++ if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
+ unixShmPurge(pDbFd);
+ }
+ unixLeaveMutex();
+@@ -28575,7 +28617,7 @@ void initUnixFile(sqlite3_file* file) {
+ int fillInUnixFile(
+ sqlite3_vfs *pVfs, /* Pointer to vfs object */
+ int h, /* Open file descriptor of file being opened */
+- int dirfd, /* Directory file descriptor */
++ int syncDir, /* True to sync directory on first sync */
+ sqlite3_file *pId, /* Write to the unixFile structure here */
+ const char *zFilename, /* Name of the file being opened */
+ int noLock, /* Omit locking if true */
+@@ -28606,7 +28648,6 @@ int fillInUnixFile(
+
+ OSTRACE(("OPEN %-3d %s\n", h, zFilename));
+ pNew->h = h;
+- pNew->dirfd = dirfd;
+ pNew->zPath = zFilename;
+ if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
+ pNew->ctrlFlags = UNIXFILE_EXCL;
+@@ -28616,6 +28657,9 @@ int fillInUnixFile(
+ if( isReadOnly ){
+ pNew->ctrlFlags |= UNIXFILE_RDONLY;
+ }
++ if( syncDir ){
++ pNew->ctrlFlags |= UNIXFILE_DIRSYNC;
++ }
+
+ #if OS_VXWORKS
+ pNew->pId = vxworksFindFileId(zFilename);
+@@ -28742,13 +28786,12 @@ int fillInUnixFile(
+ if( rc!=SQLITE_OK ){
+ if( h>=0 ) robust_close(pNew, h, __LINE__);
+ h = -1;
+- unlink(zFilename);
++ osUnlink(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;
+@@ -28758,37 +28801,6 @@ 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.
+ */
+@@ -29083,7 +29095,6 @@ 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 */
+@@ -29102,7 +29113,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 isOpenDirectory = (isCreate && (
++ int syncDir = (isCreate && (
+ eType==SQLITE_OPEN_MASTER_JOURNAL
+ || eType==SQLITE_OPEN_MAIN_JOURNAL
+ || eType==SQLITE_OPEN_WAL
+@@ -29149,7 +29160,7 @@ static int unixOpen(
+ }
+ }else if( !zName ){
+ /* If zName is NULL, the upper layer is requesting a temp file. */
+- assert(isDelete && !isOpenDirectory);
++ assert(isDelete && !syncDir);
+ rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
+ if( rc!=SQLITE_OK ){
+ return rc;
+@@ -29202,7 +29213,7 @@ static int unixOpen(
+ #if OS_VXWORKS
+ zPath = zName;
+ #else
+- unlink(zName);
++ osUnlink(zName);
+ #endif
+ }
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -29211,19 +29222,6 @@ 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
+@@ -29235,7 +29233,6 @@ 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;
+ }
+@@ -29267,9 +29264,6 @@ 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;
+@@ -29277,7 +29271,7 @@ static int unixOpen(
+ useProxy = !(fsInfo.f_flags&MNT_LOCAL);
+ }
+ if( useProxy ){
+- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
++ rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
+ isDelete, isReadonly);
+ if( rc==SQLITE_OK ){
+ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
+@@ -29295,7 +29289,7 @@ static int unixOpen(
+ }
+ #endif
+
+- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
++ rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
+ isDelete, isReadonly);
+ open_finished:
+ if( rc!=SQLITE_OK ){
+@@ -29317,13 +29311,13 @@ static int unixDelete(
+ int rc = SQLITE_OK;
+ UNUSED_PARAMETER(NotUsed);
+ SimulateIOError(return SQLITE_IOERR_DELETE);
+- if( unlink(zPath)==(-1) && errno!=ENOENT ){
++ if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
+ return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
+ }
+ #ifndef SQLITE_DISABLE_DIRSYNC
+ if( dirSync ){
+ int fd;
+- rc = openDirectory(zPath, &fd);
++ rc = osOpenDirectory(zPath, &fd);
+ if( rc==SQLITE_OK ){
+ #if OS_VXWORKS
+ if( fsync(fd)==-1 )
+@@ -29895,7 +29889,6 @@ 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;
+@@ -29960,7 +29953,7 @@ static int proxyCreateUnixFile(
+ pUnused->flags = openFlags;
+ pNew->pUnused = pUnused;
+
+- rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0);
++ rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ *ppFile = pNew;
+ return SQLITE_OK;
+@@ -30074,7 +30067,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
+ end_breaklock:
+ if( rc ){
+ if( fd>=0 ){
+- unlink(tPath);
++ osUnlink(tPath);
+ robust_close(pFile, fd, __LINE__);
+ }
+ fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
+@@ -30897,7 +30890,7 @@ SQLITE_API int sqlite3_os_init(void){
+
+ /* Double-check that the aSyscall[] array has been constructed
+ ** correctly. See ticket [bb3a86e890c8e96ab] */
+- assert( ArraySize(aSyscall)==16 );
++ assert( ArraySize(aSyscall)==18 );
+
+ /* Register all VFSes defined in the aVfs[] array */
+ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/src/src/os_unix.c
+index e5b2540..804c588 100644
+--- a/third_party/sqlite/src/src/os_unix.c
++++ b/third_party/sqlite/src/src/os_unix.c
+@@ -204,7 +204,6 @@ 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 */
+@@ -248,6 +247,7 @@ 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,6 +281,9 @@ 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
+@@ -377,6 +380,12 @@ 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 */
+
+ /*
+@@ -1731,10 +1740,6 @@ 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;
+@@ -1742,7 +1747,7 @@ static int closeUnixFile(sqlite3_file *id){
+ #if OS_VXWORKS
+ if( pFile->pId ){
+ if( pFile->isDelete ){
+- unlink(pFile->pId->zCanonicalName);
++ osUnlink(pFile->pId->zCanonicalName);
+ }
+ vxworksReleaseFileId(pFile->pId);
+ pFile->pId = 0;
+@@ -1989,7 +1994,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
+
+ /* To fully unlock the database, delete the lock file */
+ assert( eFileLock==NO_LOCK );
+- if( unlink(zLockFile) ){
++ if( osUnlink(zLockFile) ){
+ int rc = 0;
+ int tErrno = errno;
+ if( ENOENT != tErrno ){
+@@ -3226,6 +3231,50 @@ 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
+@@ -3265,28 +3314,23 @@ static int unixSync(sqlite3_file *id, int flags){
+ pFile->lastErrno = errno;
+ return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
+ }
+- if( pFile->dirfd>=0 ){
+- OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
++
++ /* 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,
+ HAVE_FULLFSYNC, isFullsync));
+-#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; */
++ 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;
+ }
+-#endif
+- /* Only need to sync once, so close the directory when we are done */
+- robust_close(pFile, pFile->dirfd, __LINE__);
+- pFile->dirfd = -1;
++ pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
+ }
+ return rc;
+ }
+@@ -4110,7 +4154,7 @@ static int unixShmUnmap(
+ assert( pShmNode->nRef>0 );
+ pShmNode->nRef--;
+ if( pShmNode->nRef==0 ){
+- if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename);
++ if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
+ unixShmPurge(pDbFd);
+ }
+ unixLeaveMutex();
+@@ -4430,7 +4474,7 @@ void initUnixFile(sqlite3_file* file) {
+ int fillInUnixFile(
+ sqlite3_vfs *pVfs, /* Pointer to vfs object */
+ int h, /* Open file descriptor of file being opened */
+- int dirfd, /* Directory file descriptor */
++ int syncDir, /* True to sync directory on first sync */
+ sqlite3_file *pId, /* Write to the unixFile structure here */
+ const char *zFilename, /* Name of the file being opened */
+ int noLock, /* Omit locking if true */
+@@ -4461,7 +4505,6 @@ int fillInUnixFile(
+
+ OSTRACE(("OPEN %-3d %s\n", h, zFilename));
+ pNew->h = h;
+- pNew->dirfd = dirfd;
+ pNew->zPath = zFilename;
+ if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
+ pNew->ctrlFlags = UNIXFILE_EXCL;
+@@ -4471,6 +4514,9 @@ int fillInUnixFile(
+ if( isReadOnly ){
+ pNew->ctrlFlags |= UNIXFILE_RDONLY;
+ }
++ if( syncDir ){
++ pNew->ctrlFlags |= UNIXFILE_DIRSYNC;
++ }
+
+ #if OS_VXWORKS
+ pNew->pId = vxworksFindFileId(zFilename);
+@@ -4597,13 +4643,12 @@ int fillInUnixFile(
+ if( rc!=SQLITE_OK ){
+ if( h>=0 ) robust_close(pNew, h, __LINE__);
+ h = -1;
+- unlink(zFilename);
++ osUnlink(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;
+@@ -4613,37 +4658,6 @@ 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.
+ */
+@@ -4938,7 +4952,6 @@ 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 */
+@@ -4957,7 +4970,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 isOpenDirectory = (isCreate && (
++ int syncDir = (isCreate && (
+ eType==SQLITE_OPEN_MASTER_JOURNAL
+ || eType==SQLITE_OPEN_MAIN_JOURNAL
+ || eType==SQLITE_OPEN_WAL
+@@ -5004,7 +5017,7 @@ static int unixOpen(
+ }
+ }else if( !zName ){
+ /* If zName is NULL, the upper layer is requesting a temp file. */
+- assert(isDelete && !isOpenDirectory);
++ assert(isDelete && !syncDir);
+ rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
+ if( rc!=SQLITE_OK ){
+ return rc;
+@@ -5057,7 +5070,7 @@ static int unixOpen(
+ #if OS_VXWORKS
+ zPath = zName;
+ #else
+- unlink(zName);
++ osUnlink(zName);
+ #endif
+ }
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -5066,19 +5079,6 @@ 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,7 +5090,6 @@ 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;
+ }
+@@ -5122,9 +5121,6 @@ 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;
+@@ -5132,7 +5128,7 @@ static int unixOpen(
+ useProxy = !(fsInfo.f_flags&MNT_LOCAL);
+ }
+ if( useProxy ){
+- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
++ rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
+ isDelete, isReadonly);
+ if( rc==SQLITE_OK ){
+ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
+@@ -5150,7 +5146,7 @@ static int unixOpen(
+ }
+ #endif
+
+- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
++ rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
+ isDelete, isReadonly);
+ open_finished:
+ if( rc!=SQLITE_OK ){
+@@ -5172,13 +5168,13 @@ static int unixDelete(
+ int rc = SQLITE_OK;
+ UNUSED_PARAMETER(NotUsed);
+ SimulateIOError(return SQLITE_IOERR_DELETE);
+- if( unlink(zPath)==(-1) && errno!=ENOENT ){
++ if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
+ return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
+ }
+ #ifndef SQLITE_DISABLE_DIRSYNC
+ if( dirSync ){
+ int fd;
+- rc = openDirectory(zPath, &fd);
++ rc = osOpenDirectory(zPath, &fd);
+ if( rc==SQLITE_OK ){
+ #if OS_VXWORKS
+ if( fsync(fd)==-1 )
+@@ -5189,6 +5185,8 @@ 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
+@@ -5750,7 +5748,6 @@ 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;
+@@ -5815,7 +5812,7 @@ static int proxyCreateUnixFile(
+ pUnused->flags = openFlags;
+ pNew->pUnused = pUnused;
+
+- rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0);
++ rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ *ppFile = pNew;
+ return SQLITE_OK;
+@@ -5929,7 +5926,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
+ end_breaklock:
+ if( rc ){
+ if( fd>=0 ){
+- unlink(tPath);
++ osUnlink(tPath);
+ robust_close(pFile, fd, __LINE__);
+ }
+ fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
+@@ -6752,7 +6749,7 @@ int sqlite3_os_init(void){
+
+ /* Double-check that the aSyscall[] array has been constructed
+ ** correctly. See ticket [bb3a86e890c8e96ab] */
+- assert( ArraySize(aSyscall)==16 );
++ assert( ArraySize(aSyscall)==18 );
+
+ /* Register all VFSes defined in the aVfs[] array */
+ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+diff --git a/third_party/sqlite/src/test/syscall.test b/third_party/sqlite/src/test/syscall.test
+index 4442612..201bd63 100644
+--- a/third_party/sqlite/src/test/syscall.test
++++ b/third_party/sqlite/src/test/syscall.test
+@@ -59,7 +59,7 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0
+ foreach s {
+ open close access getcwd stat fstat ftruncate
+ fcntl read pread write pwrite fchmod fallocate
+- pread64 pwrite64
++ pread64 pwrite64 unlink openDirectory
+ } {
+ if {[test_syscall exists $s]} {lappend syscall_list $s}
+ }
+diff --git a/third_party/sqlite/system-sqlite.patch b/third_party/sqlite/system-sqlite.patch
+index f61f019..31d6b00 100644
+--- a/third_party/sqlite/system-sqlite.patch
++++ b/third_party/sqlite/system-sqlite.patch
+@@ -1,48 +0,0 @@
+-This is a backport of http://sqlite.org/src/ci/9109128cb5,
+-which is needed for experiments with using unpatched sqlite.
+-If you hit a merge conflict on this file it is most likely
+-that you've upgraded to version of sqlite that includes this patch.
+-Index: src/os_unix.c
+-===================================================================
+---- src/os_unix.c
+-+++ src/os_unix.c
+-@@ -4787,11 +4787,11 @@
+- ** ignored and -1 is returned. The caller will try to open a new file
+- ** descriptor on the same path, fail, and return an error to SQLite.
+- **
+- ** Even if a subsequent open() call does succeed, the consequences of
+- ** not searching for a resusable file descriptor are not dire. */
+-- if( 0==stat(zPath, &sStat) ){
+-+ if( 0==osStat(zPath, &sStat) ){
+- unixInodeInfo *pInode;
+-
+- unixEnterMutex();
+- pInode = inodeList;
+- while( pInode && (pInode->fileId.dev!=sStat.st_dev
+-@@ -4863,11 +4863,11 @@
+- while( nDb>0 && zPath[nDb]!='-' ) nDb--;
+- if( nDb==0 ) return SQLITE_OK;
+- memcpy(zDb, zPath, nDb);
+- zDb[nDb] = '\0';
+-
+-- if( 0==stat(zDb, &sStat) ){
+-+ if( 0==osStat(zDb, &sStat) ){
+- *pMode = sStat.st_mode & 0777;
+- }else{
+- rc = SQLITE_IOERR_FSTAT;
+- }
+- }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
+-@@ -5208,11 +5208,11 @@
+- assert(!"Invalid flags argument");
+- }
+- *pResOut = (osAccess(zPath, amode)==0);
+- if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
+- struct stat buf;
+-- if( 0==stat(zPath, &buf) && buf.st_size==0 ){
+-+ if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
+- *pResOut = 0;
+- }
+- }
+- return SQLITE_OK;
+- }
+-
« no previous file with comments | « third_party/sqlite/src/test/syscall.test ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698