| Index: third_party/sqlite/sqlite-src-3100200/src/os_unix.c
|
| diff --git a/third_party/sqlite/sqlite-src-3080704/src/os_unix.c b/third_party/sqlite/sqlite-src-3100200/src/os_unix.c
|
| similarity index 93%
|
| copy from third_party/sqlite/sqlite-src-3080704/src/os_unix.c
|
| copy to third_party/sqlite/sqlite-src-3100200/src/os_unix.c
|
| index a9344ee830988bc4b43818e17a0c5495353b508c..791ba5d8d966f7c42c124f31767c5d0a4f6caeed 100644
|
| --- a/third_party/sqlite/sqlite-src-3080704/src/os_unix.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/os_unix.c
|
| @@ -72,18 +72,6 @@
|
| #endif
|
|
|
| /*
|
| -** Define the OS_VXWORKS pre-processor macro to 1 if building on
|
| -** vxworks, or 0 otherwise.
|
| -*/
|
| -#ifndef OS_VXWORKS
|
| -# if defined(__RTP__) || defined(_WRS_KERNEL)
|
| -# define OS_VXWORKS 1
|
| -# else
|
| -# define OS_VXWORKS 0
|
| -# endif
|
| -#endif
|
| -
|
| -/*
|
| ** standard include files.
|
| */
|
| #include <sys/types.h>
|
| @@ -97,18 +85,30 @@
|
| # include <sys/mman.h>
|
| #endif
|
|
|
| -#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
|
| +#if SQLITE_ENABLE_LOCKING_STYLE
|
| # include <sys/ioctl.h>
|
| -# if OS_VXWORKS
|
| -# include <semaphore.h>
|
| -# include <limits.h>
|
| -# else
|
| -# include <sys/file.h>
|
| -# include <sys/param.h>
|
| -# endif
|
| +# include <sys/file.h>
|
| +# include <sys/param.h>
|
| #endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
|
|
| -#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
| +#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
|
| + (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
|
| +# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
|
| + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
|
| +# define HAVE_GETHOSTUUID 1
|
| +# else
|
| +# warning "gethostuuid() is disabled."
|
| +# endif
|
| +#endif
|
| +
|
| +
|
| +#if OS_VXWORKS
|
| +# include <sys/ioctl.h>
|
| +# include <semaphore.h>
|
| +# include <limits.h>
|
| +#endif /* OS_VXWORKS */
|
| +
|
| +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
|
| # include <sys/mount.h>
|
| #endif
|
|
|
| @@ -149,6 +149,10 @@
|
| */
|
| #define MAX_PATHNAME 512
|
|
|
| +/* Always cast the getpid() return type for compatibility with
|
| +** kernel modules in VxWorks. */
|
| +#define osGetpid(X) (pid_t)getpid()
|
| +
|
| /*
|
| ** Only set the lastErrno if the error code is a real error and not
|
| ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
|
| @@ -237,7 +241,7 @@ struct unixFile {
|
| ** method was called. If xOpen() is called from a different process id,
|
| ** indicating that a fork() has occurred, the PRNG will be reset.
|
| */
|
| -static int randomnessPid = 0;
|
| +static pid_t randomnessPid = 0;
|
|
|
| /*
|
| ** Allowed values for the unixFile.ctrlFlags bitmask:
|
| @@ -254,7 +258,6 @@ static int randomnessPid = 0;
|
| #define UNIXFILE_DELETE 0x20 /* Delete on close */
|
| #define UNIXFILE_URI 0x40 /* Filename might have query parameters */
|
| #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
|
| -#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
|
|
|
| /*
|
| ** Include code that is common to all os_*.c files
|
| @@ -319,19 +322,6 @@ static int posixOpen(const char *zFile, int flags, int mode){
|
| return open(zFile, flags, mode);
|
| }
|
|
|
| -/*
|
| -** On some systems, calls to fchown() will trigger a message in a security
|
| -** log if they come from non-root processes. So avoid calling fchown() if
|
| -** we are not running as root.
|
| -*/
|
| -static int posixFchown(int fd, uid_t uid, gid_t gid){
|
| -#if OS_VXWORKS
|
| - return 0;
|
| -#else
|
| - return geteuid() ? 0 : fchown(fd,uid,gid);
|
| -#endif
|
| -}
|
| -
|
| /* Forward reference */
|
| static int openDirectory(const char*, int*);
|
| static int unixGetpagesize(void);
|
| @@ -385,7 +375,7 @@ static struct unix_syscall {
|
| { "read", (sqlite3_syscall_ptr)read, 0 },
|
| #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
|
|
|
| -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
| +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
| { "pread", (sqlite3_syscall_ptr)pread, 0 },
|
| #else
|
| { "pread", (sqlite3_syscall_ptr)0, 0 },
|
| @@ -402,7 +392,7 @@ static struct unix_syscall {
|
| { "write", (sqlite3_syscall_ptr)write, 0 },
|
| #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
|
|
|
| -#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
| +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
| { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
|
| #else
|
| { "pwrite", (sqlite3_syscall_ptr)0, 0 },
|
| @@ -418,7 +408,7 @@ static struct unix_syscall {
|
| #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
|
| aSyscall[13].pCurrent)
|
|
|
| - { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
|
| + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
|
| #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
|
|
|
| #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
|
| @@ -440,29 +430,50 @@ static struct unix_syscall {
|
| { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
|
| #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
|
|
|
| - { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
|
| + { "fchown", (sqlite3_syscall_ptr)fchown, 0 },
|
| #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
|
|
| + { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
|
| +#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
| +
|
| #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
| { "mmap", (sqlite3_syscall_ptr)mmap, 0 },
|
| -#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
|
| +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
|
|
|
| { "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
| -#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
|
| +#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
|
|
|
| #if HAVE_MREMAP
|
| { "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
| #else
|
| { "mremap", (sqlite3_syscall_ptr)0, 0 },
|
| #endif
|
| -#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
|
| +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
|
| +
|
| { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
|
| -#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
|
| +#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
|
| +
|
| + { "readlink", (sqlite3_syscall_ptr)readlink, 0 },
|
| +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
|
|
|
| #endif
|
|
|
| }; /* End of the overrideable system calls */
|
|
|
| +
|
| +/*
|
| +** On some systems, calls to fchown() will trigger a message in a security
|
| +** log if they come from non-root processes. So avoid calling fchown() if
|
| +** we are not running as root.
|
| +*/
|
| +static int robustFchown(int fd, uid_t uid, gid_t gid){
|
| +#if OS_VXWORKS
|
| + return 0;
|
| +#else
|
| + return osGeteuid() ? 0 : osFchown(fd,uid,gid);
|
| +#endif
|
| +}
|
| +
|
| /*
|
| ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
|
| ** "unix" VFSes. Return SQLITE_OK opon successfully updating the
|
| @@ -624,19 +635,19 @@ static int robust_open(const char *z, int f, mode_t m){
|
| ** unixEnterLeave()
|
| */
|
| static void unixEnterMutex(void){
|
| - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
| + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
|
| }
|
| static void unixLeaveMutex(void){
|
| - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
| + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
|
| }
|
| #ifdef SQLITE_DEBUG
|
| static int unixMutexHeld(void) {
|
| - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
| + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
|
| }
|
| #endif
|
|
|
|
|
| -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
|
| +#ifdef SQLITE_HAVE_OS_TRACE
|
| /*
|
| ** Helper function for printing out trace information from debugging
|
| ** binaries. This returns the string representation of the supplied
|
| @@ -717,9 +728,9 @@ static int lockTrace(int fd, int op, struct flock *p){
|
| /*
|
| ** Retry ftruncate() calls that fail due to EINTR
|
| **
|
| -** All calls to ftruncate() within this file should be made through this wrapper.
|
| -** On the Android platform, bypassing the logic below could lead to a corrupt
|
| -** database.
|
| +** All calls to ftruncate() within this file should be made through
|
| +** this wrapper. On the Android platform, bypassing the logic below
|
| +** could lead to a corrupt database.
|
| */
|
| static int robust_ftruncate(int h, sqlite3_int64 sz){
|
| int rc;
|
| @@ -747,23 +758,12 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){
|
| ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
|
| */
|
| static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
| + assert( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
|
| + (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
|
| + (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
|
| + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
|
| switch (posixError) {
|
| -#if 0
|
| - /* At one point this code was not commented out. In theory, this branch
|
| - ** should never be hit, as this function should only be called after
|
| - ** a locking-related function (i.e. fcntl()) has returned non-zero with
|
| - ** the value of errno as the first argument. Since a system call has failed,
|
| - ** errno should be non-zero.
|
| - **
|
| - ** Despite this, if errno really is zero, we still don't want to return
|
| - ** SQLITE_OK. The system call failed, and *some* SQLite error should be
|
| - ** propagated back to the caller. Commenting this branch out means errno==0
|
| - ** will be handled by the "default:" case below.
|
| - */
|
| - case 0:
|
| - return SQLITE_OK;
|
| -#endif
|
| -
|
| + case EACCES:
|
| case EAGAIN:
|
| case ETIMEDOUT:
|
| case EBUSY:
|
| @@ -773,41 +773,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
| * introspection, in which it actually means what it says */
|
| return SQLITE_BUSY;
|
|
|
| - case EACCES:
|
| - /* EACCES is like EAGAIN during locking operations, but not any other time*/
|
| - if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
|
| - (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
|
| - (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
|
| - (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
|
| - return SQLITE_BUSY;
|
| - }
|
| - /* else fall through */
|
| case EPERM:
|
| return SQLITE_PERM;
|
|
|
| -#if EOPNOTSUPP!=ENOTSUP
|
| - case EOPNOTSUPP:
|
| - /* something went terribly awry, unless during file system support
|
| - * introspection, in which it actually means what it says */
|
| -#endif
|
| -#ifdef ENOTSUP
|
| - case ENOTSUP:
|
| - /* invalid fd, unless during file system support introspection, in which
|
| - * it actually means what it says */
|
| -#endif
|
| - case EIO:
|
| - case EBADF:
|
| - case EINVAL:
|
| - case ENOTCONN:
|
| - case ENODEV:
|
| - case ENXIO:
|
| - case ENOENT:
|
| -#ifdef ESTALE /* ESTALE is not defined on Interix systems */
|
| - case ESTALE:
|
| -#endif
|
| - case ENOSYS:
|
| - /* these should force the client to close the file and reconnect */
|
| -
|
| default:
|
| return sqliteIOErr;
|
| }
|
| @@ -899,7 +867,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
|
|
|
| assert( zAbsoluteName[0]=='/' );
|
| n = (int)strlen(zAbsoluteName);
|
| - pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
|
| + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
|
| if( pNew==0 ) return 0;
|
| pNew->zCanonicalName = (char*)&pNew[1];
|
| memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
|
| @@ -1091,7 +1059,7 @@ static unixInodeInfo *inodeList = 0;
|
|
|
| /*
|
| **
|
| -** This function - unixLogError_x(), is only ever called via the macro
|
| +** This function - unixLogErrorAtLine(), is only ever called via the macro
|
| ** unixLogError().
|
| **
|
| ** It is invoked after an error occurs in an OS function and errno has been
|
| @@ -1179,6 +1147,14 @@ static void robust_close(unixFile *pFile, int h, int lineno){
|
| }
|
|
|
| /*
|
| +** Set the pFile->lastErrno. Do this in a subroutine as that provides
|
| +** a convenient place to set a breakpoint.
|
| +*/
|
| +static void storeLastErrno(unixFile *pFile, int error){
|
| + pFile->lastErrno = error;
|
| +}
|
| +
|
| +/*
|
| ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
|
| */
|
| static void closePendingFds(unixFile *pFile){
|
| @@ -1251,8 +1227,8 @@ static int findInodeInfo(
|
| fd = pFile->h;
|
| rc = osFstat(fd, &statbuf);
|
| if( rc!=0 ){
|
| - pFile->lastErrno = errno;
|
| -#ifdef EOVERFLOW
|
| + storeLastErrno(pFile, errno);
|
| +#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
|
| if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
|
| #endif
|
| return SQLITE_IOERR;
|
| @@ -1272,12 +1248,12 @@ static int findInodeInfo(
|
| if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
|
| do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
|
| if( rc!=1 ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return SQLITE_IOERR;
|
| }
|
| rc = osFstat(fd, &statbuf);
|
| if( rc!=0 ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return SQLITE_IOERR;
|
| }
|
| }
|
| @@ -1295,7 +1271,7 @@ static int findInodeInfo(
|
| pInode = pInode->pNext;
|
| }
|
| if( pInode==0 ){
|
| - pInode = sqlite3_malloc( sizeof(*pInode) );
|
| + pInode = sqlite3_malloc64( sizeof(*pInode) );
|
| if( pInode==0 ){
|
| return SQLITE_NOMEM;
|
| }
|
| @@ -1339,30 +1315,21 @@ static int fileHasMoved(unixFile *pFile){
|
| static void verifyDbFile(unixFile *pFile){
|
| struct stat buf;
|
| int rc;
|
| - if( pFile->ctrlFlags & UNIXFILE_WARNED ){
|
| - /* One or more of the following warnings have already been issued. Do not
|
| - ** repeat them so as not to clutter the error log */
|
| - return;
|
| - }
|
| rc = osFstat(pFile->h, &buf);
|
| if( rc!=0 ){
|
| sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
|
| - pFile->ctrlFlags |= UNIXFILE_WARNED;
|
| return;
|
| }
|
| if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
| sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
| - pFile->ctrlFlags |= UNIXFILE_WARNED;
|
| return;
|
| }
|
| if( buf.st_nlink>1 ){
|
| sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
|
| - pFile->ctrlFlags |= UNIXFILE_WARNED;
|
| return;
|
| }
|
| if( fileHasMoved(pFile) ){
|
| sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
|
| - pFile->ctrlFlags |= UNIXFILE_WARNED;
|
| return;
|
| }
|
| }
|
| @@ -1382,6 +1349,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
|
| SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
|
|
|
| assert( pFile );
|
| + assert( pFile->eFileLock<=SHARED_LOCK );
|
| unixEnterMutex(); /* Because pFile->pInode is shared across threads */
|
|
|
| /* Check if a thread in this process holds such a lock */
|
| @@ -1400,7 +1368,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
|
| lock.l_type = F_WRLCK;
|
| if( osFcntl(pFile->h, F_GETLK, &lock) ){
|
| rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| } else if( lock.l_type!=F_UNLCK ){
|
| reserved = 1;
|
| }
|
| @@ -1438,9 +1406,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
|
| unixInodeInfo *pInode = pFile->pInode;
|
| assert( unixMutexHeld() );
|
| assert( pInode!=0 );
|
| - if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
|
| - && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
|
| - ){
|
| + if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
|
| if( pInode->bProcessLock==0 ){
|
| struct flock lock;
|
| assert( pInode->nLock==0 );
|
| @@ -1533,7 +1499,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
| assert( pFile );
|
| OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
|
| azFileLock(eFileLock), azFileLock(pFile->eFileLock),
|
| - azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
|
| + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared,
|
| + osGetpid(0)));
|
|
|
| /* If there is already a lock of this type or more restrictive on the
|
| ** unixFile, do nothing. Don't use the end_lock: exit path, as
|
| @@ -1600,7 +1567,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
| tErrno = errno;
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
| if( rc!=SQLITE_BUSY ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| goto end_lock;
|
| }
|
| @@ -1635,7 +1602,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
|
|
| if( rc ){
|
| if( rc!=SQLITE_BUSY ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| goto end_lock;
|
| }else{
|
| @@ -1668,7 +1635,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
| tErrno = errno;
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
| if( rc!=SQLITE_BUSY ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| }
|
| }
|
| @@ -1741,7 +1708,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| assert( pFile );
|
| OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
|
| pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
|
| - getpid()));
|
| + osGetpid(0)));
|
|
|
| assert( eFileLock<=SHARED_LOCK );
|
| if( pFile->eFileLock<=eFileLock ){
|
| @@ -1775,7 +1742,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| ** 4: [RRRR.]
|
| */
|
| if( eFileLock==SHARED_LOCK ){
|
| -
|
| #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
|
| (void)handleNFSUnlock;
|
| assert( handleNFSUnlock==0 );
|
| @@ -1792,9 +1758,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| if( unixFileLock(pFile, &lock)==(-1) ){
|
| tErrno = errno;
|
| rc = SQLITE_IOERR_UNLOCK;
|
| - if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| - }
|
| + storeLastErrno(pFile, tErrno);
|
| goto end_unlock;
|
| }
|
| lock.l_type = F_RDLCK;
|
| @@ -1805,7 +1769,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| tErrno = errno;
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
|
| if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| goto end_unlock;
|
| }
|
| @@ -1816,9 +1780,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| if( unixFileLock(pFile, &lock)==(-1) ){
|
| tErrno = errno;
|
| rc = SQLITE_IOERR_UNLOCK;
|
| - if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| - }
|
| + storeLastErrno(pFile, tErrno);
|
| goto end_unlock;
|
| }
|
| }else
|
| @@ -1836,7 +1798,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| ** SQLITE_BUSY would confuse the upper layer (in practice it causes
|
| ** an assert to fail). */
|
| rc = SQLITE_IOERR_RDLOCK;
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| goto end_unlock;
|
| }
|
| }
|
| @@ -1849,7 +1811,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| pInode->eFileLock = SHARED_LOCK;
|
| }else{
|
| rc = SQLITE_IOERR_UNLOCK;
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| goto end_unlock;
|
| }
|
| }
|
| @@ -1867,7 +1829,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
|
| pInode->eFileLock = NO_LOCK;
|
| }else{
|
| rc = SQLITE_IOERR_UNLOCK;
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| pInode->eFileLock = NO_LOCK;
|
| pFile->eFileLock = NO_LOCK;
|
| }
|
| @@ -2069,17 +2031,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
| SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
|
|
|
| assert( pFile );
|
| -
|
| - /* Check if a thread in this process holds such a lock */
|
| - if( pFile->eFileLock>SHARED_LOCK ){
|
| - /* Either this connection or some other connection in the same process
|
| - ** holds a lock on the file. No need to check further. */
|
| - reserved = 1;
|
| - }else{
|
| - /* The lock is held if and only if the lockfile exists */
|
| - const char *zLockFile = (const char*)pFile->lockingContext;
|
| - reserved = osAccess(zLockFile, 0)==0;
|
| - }
|
| + reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
|
| OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
|
| *pResOut = reserved;
|
| return rc;
|
| @@ -2141,8 +2093,8 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
|
| rc = SQLITE_BUSY;
|
| } else {
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
| - if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + if( rc!=SQLITE_BUSY ){
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| }
|
| return rc;
|
| @@ -2169,7 +2121,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
|
|
| assert( pFile );
|
| OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
|
| - pFile->eFileLock, getpid()));
|
| + pFile->eFileLock, osGetpid(0)));
|
| assert( eFileLock<=SHARED_LOCK );
|
|
|
| /* no-op if possible */
|
| @@ -2188,15 +2140,13 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
| /* To fully unlock the database, delete the lock file */
|
| assert( eFileLock==NO_LOCK );
|
| rc = osRmdir(zLockFile);
|
| - if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
|
| if( rc<0 ){
|
| int tErrno = errno;
|
| - rc = 0;
|
| - if( ENOENT != tErrno ){
|
| + if( tErrno==ENOENT ){
|
| + rc = SQLITE_OK;
|
| + }else{
|
| rc = SQLITE_IOERR_UNLOCK;
|
| - }
|
| - if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| return rc;
|
| }
|
| @@ -2208,14 +2158,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
|
| ** Close a file. Make sure the lock has been released before closing.
|
| */
|
| static int dotlockClose(sqlite3_file *id) {
|
| - int rc = SQLITE_OK;
|
| - if( id ){
|
| - unixFile *pFile = (unixFile*)id;
|
| - dotlockUnlock(id, NO_LOCK);
|
| - sqlite3_free(pFile->lockingContext);
|
| - rc = closeUnixFile(id);
|
| - }
|
| - return rc;
|
| + unixFile *pFile = (unixFile*)id;
|
| + assert( id!=0 );
|
| + dotlockUnlock(id, NO_LOCK);
|
| + sqlite3_free(pFile->lockingContext);
|
| + return closeUnixFile(id);
|
| }
|
| /****************** End of the dot-file lock implementation *******************
|
| ******************************************************************************/
|
| @@ -2232,10 +2179,9 @@ static int dotlockClose(sqlite3_file *id) {
|
| ** still works when you do this, but concurrency is reduced since
|
| ** only a single process can be reading the database at a time.
|
| **
|
| -** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
|
| -** compiling for VXWORKS.
|
| +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off
|
| */
|
| -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
| +#if SQLITE_ENABLE_LOCKING_STYLE
|
|
|
| /*
|
| ** Retry flock() calls that fail with EINTR
|
| @@ -2282,10 +2228,8 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
| int tErrno = errno;
|
| /* unlock failed with an error */
|
| lrc = SQLITE_IOERR_UNLOCK;
|
| - if( IS_LOCK_ERROR(lrc) ){
|
| - pFile->lastErrno = tErrno;
|
| - rc = lrc;
|
| - }
|
| + storeLastErrno(pFile, tErrno);
|
| + rc = lrc;
|
| }
|
| } else {
|
| int tErrno = errno;
|
| @@ -2293,7 +2237,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
| /* someone else might have it reserved */
|
| lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
| if( IS_LOCK_ERROR(lrc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| rc = lrc;
|
| }
|
| }
|
| @@ -2359,7 +2303,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
|
| /* didn't get, must be busy */
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
| if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| } else {
|
| /* got it, set the type and return ok */
|
| @@ -2388,7 +2332,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
|
|
|
| assert( pFile );
|
| OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
|
| - pFile->eFileLock, getpid()));
|
| + pFile->eFileLock, osGetpid(0)));
|
| assert( eFileLock<=SHARED_LOCK );
|
|
|
| /* no-op if possible */
|
| @@ -2418,12 +2362,9 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
|
| ** Close a file.
|
| */
|
| static int flockClose(sqlite3_file *id) {
|
| - int rc = SQLITE_OK;
|
| - if( id ){
|
| - flockUnlock(id, NO_LOCK);
|
| - rc = closeUnixFile(id);
|
| - }
|
| - return rc;
|
| + assert( id!=0 );
|
| + flockUnlock(id, NO_LOCK);
|
| + return closeUnixFile(id);
|
| }
|
|
|
| #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
|
| @@ -2449,7 +2390,7 @@ static int flockClose(sqlite3_file *id) {
|
| ** to a non-zero value otherwise *pResOut is set to zero. The return value
|
| ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
|
| */
|
| -static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
| +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
| int rc = SQLITE_OK;
|
| int reserved = 0;
|
| unixFile *pFile = (unixFile*)id;
|
| @@ -2471,7 +2412,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
| int tErrno = errno;
|
| if( EAGAIN != tErrno ){
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| } else {
|
| /* someone else has the lock when we are in NO_LOCK */
|
| reserved = (pFile->eFileLock < SHARED_LOCK);
|
| @@ -2516,7 +2457,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
| ** This routine will only increase a lock. Use the sqlite3OsUnlock()
|
| ** routine to lower a locking level.
|
| */
|
| -static int semLock(sqlite3_file *id, int eFileLock) {
|
| +static int semXLock(sqlite3_file *id, int eFileLock) {
|
| unixFile *pFile = (unixFile*)id;
|
| sem_t *pSem = pFile->pInode->pSem;
|
| int rc = SQLITE_OK;
|
| @@ -2549,14 +2490,14 @@ static int semLock(sqlite3_file *id, int eFileLock) {
|
| ** If the locking level of the file descriptor is already at or below
|
| ** the requested locking level, this routine is a no-op.
|
| */
|
| -static int semUnlock(sqlite3_file *id, int eFileLock) {
|
| +static int semXUnlock(sqlite3_file *id, int eFileLock) {
|
| unixFile *pFile = (unixFile*)id;
|
| sem_t *pSem = pFile->pInode->pSem;
|
|
|
| assert( pFile );
|
| assert( pSem );
|
| OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
|
| - pFile->eFileLock, getpid()));
|
| + pFile->eFileLock, osGetpid(0)));
|
| assert( eFileLock<=SHARED_LOCK );
|
|
|
| /* no-op if possible */
|
| @@ -2575,7 +2516,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
|
| int rc, tErrno = errno;
|
| rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
|
| if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| return rc;
|
| }
|
| @@ -2586,10 +2527,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
|
| /*
|
| ** Close a file.
|
| */
|
| -static int semClose(sqlite3_file *id) {
|
| +static int semXClose(sqlite3_file *id) {
|
| if( id ){
|
| unixFile *pFile = (unixFile*)id;
|
| - semUnlock(id, NO_LOCK);
|
| + semXUnlock(id, NO_LOCK);
|
| assert( pFile );
|
| unixEnterMutex();
|
| releaseInodeInfo(pFile);
|
| @@ -2677,7 +2618,7 @@ static int afpSetLock(
|
| setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
|
| #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
|
| if( IS_LOCK_ERROR(rc) ){
|
| - pFile->lastErrno = tErrno;
|
| + storeLastErrno(pFile, tErrno);
|
| }
|
| return rc;
|
| } else {
|
| @@ -2770,7 +2711,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
|
| assert( pFile );
|
| OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
|
| azFileLock(eFileLock), azFileLock(pFile->eFileLock),
|
| - azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
|
| + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0)));
|
|
|
| /* If there is already a lock of this type or more restrictive on the
|
| ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
|
| @@ -2860,7 +2801,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
|
| lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
|
|
|
| if( IS_LOCK_ERROR(lrc1) ) {
|
| - pFile->lastErrno = lrc1Errno;
|
| + storeLastErrno(pFile, lrc1Errno);
|
| rc = lrc1;
|
| goto afp_end_lock;
|
| } else if( IS_LOCK_ERROR(lrc2) ){
|
| @@ -2956,7 +2897,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
|
| assert( pFile );
|
| OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
|
| pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
|
| - getpid()));
|
| + osGetpid(0)));
|
|
|
| assert( eFileLock<=SHARED_LOCK );
|
| if( pFile->eFileLock<=eFileLock ){
|
| @@ -3048,23 +2989,22 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
|
| */
|
| static int afpClose(sqlite3_file *id) {
|
| int rc = SQLITE_OK;
|
| - if( id ){
|
| - unixFile *pFile = (unixFile*)id;
|
| - afpUnlock(id, NO_LOCK);
|
| - unixEnterMutex();
|
| - if( pFile->pInode && pFile->pInode->nLock ){
|
| - /* If there are outstanding locks, do not actually close the file just
|
| - ** yet because that would clear those locks. Instead, add the file
|
| - ** descriptor to pInode->aPending. It will be automatically closed when
|
| - ** the last lock is cleared.
|
| - */
|
| - setPendingFd(pFile);
|
| - }
|
| - releaseInodeInfo(pFile);
|
| - sqlite3_free(pFile->lockingContext);
|
| - rc = closeUnixFile(id);
|
| - unixLeaveMutex();
|
| + unixFile *pFile = (unixFile*)id;
|
| + assert( id!=0 );
|
| + afpUnlock(id, NO_LOCK);
|
| + unixEnterMutex();
|
| + if( pFile->pInode && pFile->pInode->nLock ){
|
| + /* If there are outstanding locks, do not actually close the file just
|
| + ** yet because that would clear those locks. Instead, add the file
|
| + ** descriptor to pInode->aPending. It will be automatically closed when
|
| + ** the last lock is cleared.
|
| + */
|
| + setPendingFd(pFile);
|
| }
|
| + releaseInodeInfo(pFile);
|
| + sqlite3_free(pFile->lockingContext);
|
| + rc = closeUnixFile(id);
|
| + unixLeaveMutex();
|
| return rc;
|
| }
|
|
|
| @@ -3134,7 +3074,6 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
| TIMER_START;
|
| assert( cnt==(cnt&0x1ffff) );
|
| assert( id->h>2 );
|
| - cnt &= 0x1ffff;
|
| do{
|
| #if defined(USE_PREAD)
|
| got = osPread(id->h, pBuf, cnt, offset);
|
| @@ -3144,13 +3083,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
| SimulateIOError( got = -1 );
|
| #else
|
| newOffset = lseek(id->h, offset, SEEK_SET);
|
| - SimulateIOError( newOffset-- );
|
| - if( newOffset!=offset ){
|
| - if( newOffset == -1 ){
|
| - ((unixFile*)id)->lastErrno = errno;
|
| - }else{
|
| - ((unixFile*)id)->lastErrno = 0;
|
| - }
|
| + SimulateIOError( newOffset = -1 );
|
| + if( newOffset<0 ){
|
| + storeLastErrno((unixFile*)id, errno);
|
| return -1;
|
| }
|
| got = osRead(id->h, pBuf, cnt);
|
| @@ -3159,7 +3094,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
|
| if( got<0 ){
|
| if( errno==EINTR ){ got = 1; continue; }
|
| prior = 0;
|
| - ((unixFile*)id)->lastErrno = errno;
|
| + storeLastErrno((unixFile*)id, errno);
|
| break;
|
| }else if( got>0 ){
|
| cnt -= got;
|
| @@ -3224,7 +3159,7 @@ static int unixRead(
|
| /* lastErrno set by seekAndRead */
|
| return SQLITE_IOERR_READ;
|
| }else{
|
| - pFile->lastErrno = 0; /* not a system error */
|
| + storeLastErrno(pFile, 0); /* not a system error */
|
| /* Unread parts of the buffer must be zero-filled */
|
| memset(&((char*)pBuf)[got], 0, amt-got);
|
| return SQLITE_IOERR_SHORT_READ;
|
| @@ -3249,21 +3184,21 @@ static int seekAndWriteFd(
|
|
|
| assert( nBuf==(nBuf&0x1ffff) );
|
| assert( fd>2 );
|
| + assert( piErrno!=0 );
|
| nBuf &= 0x1ffff;
|
| TIMER_START;
|
|
|
| #if defined(USE_PREAD)
|
| - do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
|
| + do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
|
| #elif defined(USE_PREAD64)
|
| - do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
|
| + do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
|
| #else
|
| do{
|
| i64 iSeek = lseek(fd, iOff, SEEK_SET);
|
| - SimulateIOError( iSeek-- );
|
| -
|
| - if( iSeek!=iOff ){
|
| - if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
|
| - return -1;
|
| + SimulateIOError( iSeek = -1 );
|
| + if( iSeek<0 ){
|
| + rc = -1;
|
| + break;
|
| }
|
| rc = osWrite(fd, pBuf, nBuf);
|
| }while( rc<0 && errno==EINTR );
|
| @@ -3272,7 +3207,7 @@ static int seekAndWriteFd(
|
| TIMER_END;
|
| OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
|
|
|
| - if( rc<0 && piErrno ) *piErrno = errno;
|
| + if( rc<0 ) *piErrno = errno;
|
| return rc;
|
| }
|
|
|
| @@ -3335,7 +3270,7 @@ static int unixWrite(
|
| }
|
| #endif
|
|
|
| -#if SQLITE_MAX_MMAP_SIZE>0
|
| +#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
|
| /* Deal with as much of this write request as possible by transfering
|
| ** data from the memory mapping using memcpy(). */
|
| if( offset<pFile->mmapSize ){
|
| @@ -3351,8 +3286,8 @@ static int unixWrite(
|
| }
|
| }
|
| #endif
|
| -
|
| - while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
|
| +
|
| + while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
|
| amt -= wrote;
|
| offset += wrote;
|
| pBuf = &((char*)pBuf)[wrote];
|
| @@ -3360,12 +3295,12 @@ static int unixWrite(
|
| SimulateIOError(( wrote=(-1), amt=1 ));
|
| SimulateDiskfullError(( wrote=0, amt=1 ));
|
|
|
| - if( amt>0 ){
|
| + if( amt>wrote ){
|
| if( wrote<0 && pFile->lastErrno!=ENOSPC ){
|
| /* lastErrno set by seekAndWrite */
|
| return SQLITE_IOERR_WRITE;
|
| }else{
|
| - pFile->lastErrno = 0; /* not a system error */
|
| + storeLastErrno(pFile, 0); /* not a system error */
|
| return SQLITE_FULL;
|
| }
|
| }
|
| @@ -3386,9 +3321,9 @@ int sqlite3_fullsync_count = 0;
|
| ** We do not trust systems to provide a working fdatasync(). Some do.
|
| ** Others do no. To be safe, we will stick with the (slightly slower)
|
| ** fsync(). If you know that your system does support fdatasync() correctly,
|
| -** then simply compile with -Dfdatasync=fdatasync
|
| +** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC
|
| */
|
| -#if !defined(fdatasync)
|
| +#if !defined(fdatasync) && !HAVE_FDATASYNC
|
| # define fdatasync fsync
|
| #endif
|
|
|
| @@ -3456,10 +3391,15 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
|
| #endif
|
|
|
| /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
|
| - ** no-op
|
| + ** no-op. But go ahead and call fstat() to validate the file
|
| + ** descriptor as we need a method to provoke a failure during
|
| + ** coverate testing.
|
| */
|
| #ifdef SQLITE_NO_SYNC
|
| - rc = SQLITE_OK;
|
| + {
|
| + struct stat buf;
|
| + rc = osFstat(fd, &buf);
|
| + }
|
| #elif HAVE_FULLFSYNC
|
| if( fullSync ){
|
| rc = osFcntl(fd, F_FULLFSYNC, 0);
|
| @@ -3525,16 +3465,20 @@ static int openDirectory(const char *zFilename, int *pFd){
|
| char zDirname[MAX_PATHNAME+1];
|
|
|
| sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
|
| - for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
|
| + for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--);
|
| if( ii>0 ){
|
| zDirname[ii] = '\0';
|
| - fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
|
| - if( fd>=0 ){
|
| - OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
|
| - }
|
| + }else{
|
| + if( zDirname[0]!='/' ) zDirname[0] = '.';
|
| + zDirname[1] = 0;
|
| + }
|
| + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
|
| + if( fd>=0 ){
|
| + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
|
| }
|
| *pFd = fd;
|
| - return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
|
| + if( fd>=0 ) return SQLITE_OK;
|
| + return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
|
| }
|
|
|
| /*
|
| @@ -3574,7 +3518,7 @@ static int unixSync(sqlite3_file *id, int flags){
|
| rc = full_fsync(pFile->h, isFullsync, isDataOnly);
|
| SimulateIOError( rc=1 );
|
| if( rc ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
|
| }
|
|
|
| @@ -3587,10 +3531,11 @@ static int unixSync(sqlite3_file *id, int flags){
|
| OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
|
| HAVE_FULLFSYNC, isFullsync));
|
| rc = osOpenDirectory(pFile->zPath, &dirfd);
|
| - if( rc==SQLITE_OK && dirfd>=0 ){
|
| + if( rc==SQLITE_OK ){
|
| full_fsync(dirfd, 0, 0);
|
| robust_close(pFile, dirfd, __LINE__);
|
| - }else if( rc==SQLITE_CANTOPEN ){
|
| + }else{
|
| + assert( rc==SQLITE_CANTOPEN );
|
| rc = SQLITE_OK;
|
| }
|
| pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
|
| @@ -3618,7 +3563,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
|
|
| rc = robust_ftruncate(pFile->h, nByte);
|
| if( rc ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
| }else{
|
| #ifdef SQLITE_DEBUG
|
| @@ -3658,7 +3603,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
|
| rc = osFstat(((unixFile*)id)->h, &buf);
|
| SimulateIOError( rc=1 );
|
| if( rc!=0 ){
|
| - ((unixFile*)id)->lastErrno = errno;
|
| + storeLastErrno((unixFile*)id, errno);
|
| return SQLITE_IOERR_FSTAT;
|
| }
|
| *pSize = buf.st_size;
|
| @@ -3694,7 +3639,9 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
| i64 nSize; /* Required file size */
|
| struct stat buf; /* Used to hold return values of fstat() */
|
|
|
| - if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
|
| + if( osFstat(pFile->h, &buf) ){
|
| + return SQLITE_IOERR_FSTAT;
|
| + }
|
|
|
| nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
| if( nSize>(i64)buf.st_size ){
|
| @@ -3709,24 +3656,24 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
| }while( err==EINTR );
|
| if( err ) return SQLITE_IOERR_WRITE;
|
| #else
|
| - /* If the OS does not have posix_fallocate(), fake it. First use
|
| - ** ftruncate() to set the file size, then write a single byte to
|
| - ** the last byte in each block within the extended region. This
|
| - ** is the same technique used by glibc to implement posix_fallocate()
|
| - ** on systems that do not have a real fallocate() system call.
|
| + /* If the OS does not have posix_fallocate(), fake it. Write a
|
| + ** single byte to the last byte in each block that falls entirely
|
| + ** within the extended region. Then, if required, a single byte
|
| + ** at offset (nSize-1), to set the size of the file correctly.
|
| + ** This is a similar technique to that used by glibc on systems
|
| + ** that do not have a real fallocate() call.
|
| */
|
| int nBlk = buf.st_blksize; /* File-system block size */
|
| + int nWrite = 0; /* Number of bytes written by seekAndWrite */
|
| i64 iWrite; /* Next offset to write to */
|
|
|
| - if( robust_ftruncate(pFile->h, nSize) ){
|
| - pFile->lastErrno = errno;
|
| - return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
| - }
|
| - iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
|
| - while( iWrite<nSize ){
|
| - int nWrite = seekAndWrite(pFile, iWrite, "", 1);
|
| + iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
|
| + assert( iWrite>=buf.st_size );
|
| + assert( ((iWrite+1)%nBlk)==0 );
|
| + for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
|
| + if( iWrite>=nSize ) iWrite = nSize - 1;
|
| + nWrite = seekAndWrite(pFile, iWrite, "", 1);
|
| if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
|
| - iWrite += nBlk;
|
| }
|
| #endif
|
| }
|
| @@ -3737,7 +3684,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
| int rc;
|
| if( pFile->szChunk<=0 ){
|
| if( robust_ftruncate(pFile->h, nByte) ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
| }
|
| }
|
| @@ -3779,7 +3726,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
| *(int*)pArg = pFile->eFileLock;
|
| return SQLITE_OK;
|
| }
|
| - case SQLITE_LAST_ERRNO: {
|
| + case SQLITE_FCNTL_LAST_ERRNO: {
|
| *(int*)pArg = pFile->lastErrno;
|
| return SQLITE_OK;
|
| }
|
| @@ -3807,7 +3754,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
| return SQLITE_OK;
|
| }
|
| case SQLITE_FCNTL_TEMPFILENAME: {
|
| - char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
|
| + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
|
| if( zTFile ){
|
| unixGetTempname(pFile->pVfs->mxPathname, zTFile);
|
| *(char**)pArg = zTFile;
|
| @@ -3848,8 +3795,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
| }
|
| #endif
|
| #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
| - case SQLITE_SET_LOCKPROXYFILE:
|
| - case SQLITE_GET_LOCKPROXYFILE: {
|
| + case SQLITE_FCNTL_SET_LOCKPROXYFILE:
|
| + case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
|
| return proxyFileControl(id,op,pArg);
|
| }
|
| #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
|
| @@ -3989,7 +3936,9 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
|
| ** Instead, it should be called via macro osGetpagesize().
|
| */
|
| static int unixGetpagesize(void){
|
| -#if defined(_BSD_SOURCE)
|
| +#if OS_VXWORKS
|
| + return 1024;
|
| +#elif defined(_BSD_SOURCE)
|
| return getpagesize();
|
| #else
|
| return (int)sysconf(_SC_PAGESIZE);
|
| @@ -4082,22 +4031,24 @@ struct unixShm {
|
| ** otherwise.
|
| */
|
| static int unixShmSystemLock(
|
| - unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
|
| + unixFile *pFile, /* Open connection to the WAL file */
|
| int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */
|
| int ofst, /* First byte of the locking range */
|
| int n /* Number of bytes to lock */
|
| ){
|
| - struct flock f; /* The posix advisory locking structure */
|
| - int rc = SQLITE_OK; /* Result code form fcntl() */
|
| + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
|
| + struct flock f; /* The posix advisory locking structure */
|
| + int rc = SQLITE_OK; /* Result code form fcntl() */
|
|
|
| /* Access to the unixShmNode object is serialized by the caller */
|
| + pShmNode = pFile->pInode->pShmNode;
|
| assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
|
|
|
| /* Shared locks never span more than one byte */
|
| assert( n==1 || lockType!=F_RDLCK );
|
|
|
| /* Locks are within range */
|
| - assert( n>=1 && n<SQLITE_SHM_NLOCK );
|
| + assert( n>=1 && n<=SQLITE_SHM_NLOCK );
|
|
|
| if( pShmNode->h>=0 ){
|
| /* Initialize the locking parameters */
|
| @@ -4175,7 +4126,7 @@ static int unixShmRegionPerMap(void){
|
| static void unixShmPurge(unixFile *pFd){
|
| unixShmNode *p = pFd->pInode->pShmNode;
|
| assert( unixMutexHeld() );
|
| - if( p && p->nRef==0 ){
|
| + if( p && ALWAYS(p->nRef==0) ){
|
| int nShmPerMap = unixShmRegionPerMap();
|
| int i;
|
| assert( p->pInode==pFd->pInode );
|
| @@ -4241,7 +4192,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
| int nShmFilename; /* Size of the SHM filename in bytes */
|
|
|
| /* Allocate space for the new unixShm object. */
|
| - p = sqlite3_malloc( sizeof(*p) );
|
| + p = sqlite3_malloc64( sizeof(*p) );
|
| if( p==0 ) return SQLITE_NOMEM;
|
| memset(p, 0, sizeof(*p));
|
| assert( pDbFd->pShm==0 );
|
| @@ -4254,12 +4205,15 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
| pShmNode = pInode->pShmNode;
|
| if( pShmNode==0 ){
|
| struct stat sStat; /* fstat() info for database file */
|
| +#ifndef SQLITE_SHM_DIRECTORY
|
| + const char *zBasePath = pDbFd->zPath;
|
| +#endif
|
|
|
| /* Call fstat() to figure out the permissions on the database file. If
|
| ** a new *-shm file is created, an attempt will be made to create it
|
| ** with the same permissions.
|
| */
|
| - if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
|
| + if( osFstat(pDbFd->h, &sStat) ){
|
| rc = SQLITE_IOERR_FSTAT;
|
| goto shm_open_err;
|
| }
|
| @@ -4267,9 +4221,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
| #ifdef SQLITE_SHM_DIRECTORY
|
| nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
|
| #else
|
| - nShmFilename = 6 + (int)strlen(pDbFd->zPath);
|
| + nShmFilename = 6 + (int)strlen(zBasePath);
|
| #endif
|
| - pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
|
| + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
|
| if( pShmNode==0 ){
|
| rc = SQLITE_NOMEM;
|
| goto shm_open_err;
|
| @@ -4281,7 +4235,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
| SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
|
| (u32)sStat.st_ino, (u32)sStat.st_dev);
|
| #else
|
| - sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
|
| + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
|
| sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
|
| #endif
|
| pShmNode->h = -1;
|
| @@ -4309,19 +4263,19 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
| ** is owned by the same user that owns the original database. Otherwise,
|
| ** the original owner will not be able to connect.
|
| */
|
| - osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
|
| + robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
|
|
|
| /* Check to see if another process is holding the dead-man switch.
|
| ** If not, truncate the file to zero length.
|
| */
|
| rc = SQLITE_OK;
|
| - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
|
| + if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
|
| if( robust_ftruncate(pShmNode->h, 0) ){
|
| rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
|
| }
|
| }
|
| if( rc==SQLITE_OK ){
|
| - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
|
| + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
|
| }
|
| if( rc ) goto shm_open_err;
|
| }
|
| @@ -4446,7 +4400,8 @@ static int unixShmMap(
|
| /* Write to the last byte of each newly allocated or extended page */
|
| assert( (nByte % pgsz)==0 );
|
| for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
|
| - if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
|
| + int x = 0;
|
| + if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
|
| const char *zFile = pShmNode->zFilename;
|
| rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
|
| goto shmpage_out;
|
| @@ -4479,7 +4434,7 @@ static int unixShmMap(
|
| goto shmpage_out;
|
| }
|
| }else{
|
| - pMem = sqlite3_malloc(szRegion);
|
| + pMem = sqlite3_malloc64(szRegion);
|
| if( pMem==0 ){
|
| rc = SQLITE_NOMEM;
|
| goto shmpage_out;
|
| @@ -4553,7 +4508,7 @@ static int unixShmLock(
|
|
|
| /* Unlock the system-level locks */
|
| if( (mask & allMask)==0 ){
|
| - rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
| + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
| }else{
|
| rc = SQLITE_OK;
|
| }
|
| @@ -4581,7 +4536,7 @@ static int unixShmLock(
|
| /* Get shared locks at the system level, if necessary */
|
| if( rc==SQLITE_OK ){
|
| if( (allShared & mask)==0 ){
|
| - rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
|
| + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
|
| }else{
|
| rc = SQLITE_OK;
|
| }
|
| @@ -4606,7 +4561,7 @@ static int unixShmLock(
|
| ** also mark the local connection as being locked.
|
| */
|
| if( rc==SQLITE_OK ){
|
| - rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
|
| + rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
|
| if( rc==SQLITE_OK ){
|
| assert( (p->sharedMask & mask)==0 );
|
| p->exclMask |= mask;
|
| @@ -4615,7 +4570,7 @@ static int unixShmLock(
|
| }
|
| sqlite3_mutex_leave(pShmNode->mutex);
|
| OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
|
| - p->id, getpid(), p->sharedMask, p->exclMask));
|
| + p->id, osGetpid(0), p->sharedMask, p->exclMask));
|
| return rc;
|
| }
|
|
|
| @@ -4629,7 +4584,8 @@ static void unixShmBarrier(
|
| sqlite3_file *fd /* Database file holding the shared memory */
|
| ){
|
| UNUSED_PARAMETER(fd);
|
| - unixEnterMutex();
|
| + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
|
| + unixEnterMutex(); /* Also mutex, for redundancy */
|
| unixLeaveMutex();
|
| }
|
|
|
| @@ -4674,7 +4630,9 @@ 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 ){
|
| + osUnlink(pShmNode->zFilename);
|
| + }
|
| unixShmPurge(pDbFd);
|
| }
|
| unixLeaveMutex();
|
| @@ -4737,7 +4695,9 @@ static void unixRemapfile(
|
| assert( pFd->mmapSizeActual>=pFd->mmapSize );
|
| assert( MAP_FAILED!=0 );
|
|
|
| +#ifdef SQLITE_MMAP_READWRITE
|
| if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
| +#endif
|
|
|
| if( pOrig ){
|
| #if HAVE_MREMAP
|
| @@ -4809,17 +4769,14 @@ static void unixRemapfile(
|
| ** recreated as a result of outstanding references) or an SQLite error
|
| ** code otherwise.
|
| */
|
| -static int unixMapfile(unixFile *pFd, i64 nByte){
|
| - i64 nMap = nByte;
|
| - int rc;
|
| -
|
| +static int unixMapfile(unixFile *pFd, i64 nMap){
|
| assert( nMap>=0 || pFd->nFetchOut==0 );
|
| + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
|
| if( pFd->nFetchOut>0 ) return SQLITE_OK;
|
|
|
| if( nMap<0 ){
|
| struct stat statbuf; /* Low-level file information */
|
| - rc = osFstat(pFd->h, &statbuf);
|
| - if( rc!=SQLITE_OK ){
|
| + if( osFstat(pFd->h, &statbuf) ){
|
| return SQLITE_IOERR_FSTAT;
|
| }
|
| nMap = statbuf.st_size;
|
| @@ -4828,12 +4785,9 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
|
| nMap = pFd->mmapSizeMax;
|
| }
|
|
|
| + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
|
| if( nMap!=pFd->mmapSize ){
|
| - if( nMap>0 ){
|
| - unixRemapfile(pFd, nMap);
|
| - }else{
|
| - unixUnmapfile(pFd);
|
| - }
|
| + unixRemapfile(pFd, nMap);
|
| }
|
|
|
| return SQLITE_OK;
|
| @@ -4951,7 +4905,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
|
| ** * An I/O method finder function called FINDER that returns a pointer
|
| ** to the METHOD object in the previous bullet.
|
| */
|
| -#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
|
| +#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \
|
| static const sqlite3_io_methods METHOD = { \
|
| VERSION, /* iVersion */ \
|
| CLOSE, /* xClose */ \
|
| @@ -5016,7 +4970,7 @@ IOMETHODS(
|
| 0 /* xShmMap method */
|
| )
|
|
|
| -#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
| +#if SQLITE_ENABLE_LOCKING_STYLE
|
| IOMETHODS(
|
| flockIoFinder, /* Finder function name */
|
| flockIoMethods, /* sqlite3_io_methods object name */
|
| @@ -5034,10 +4988,10 @@ IOMETHODS(
|
| semIoFinder, /* Finder function name */
|
| semIoMethods, /* sqlite3_io_methods object name */
|
| 1, /* shared memory is disabled */
|
| - semClose, /* xClose method */
|
| - semLock, /* xLock method */
|
| - semUnlock, /* xUnlock method */
|
| - semCheckReservedLock, /* xCheckReservedLock method */
|
| + semXClose, /* xClose method */
|
| + semXLock, /* xLock method */
|
| + semXUnlock, /* xUnlock method */
|
| + semXCheckReservedLock, /* xCheckReservedLock method */
|
| 0 /* xShmMap method */
|
| )
|
| #endif
|
| @@ -5161,15 +5115,13 @@ static const sqlite3_io_methods
|
|
|
| #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
|
|
|
| -#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
|
| -/*
|
| -** This "finder" function attempts to determine the best locking strategy
|
| -** for the database file "filePath". It then returns the sqlite3_io_methods
|
| -** object that implements that strategy.
|
| -**
|
| -** This is for VXWorks only.
|
| +#if OS_VXWORKS
|
| +/*
|
| +** This "finder" function for VxWorks checks to see if posix advisory
|
| +** locking works. If it does, then that is what is used. If it does not
|
| +** work, then fallback to named semaphore locking.
|
| */
|
| -static const sqlite3_io_methods *autolockIoFinderImpl(
|
| +static const sqlite3_io_methods *vxworksIoFinderImpl(
|
| const char *filePath, /* name of the database file */
|
| unixFile *pNew /* the open file object */
|
| ){
|
| @@ -5195,9 +5147,9 @@ static const sqlite3_io_methods *autolockIoFinderImpl(
|
| }
|
| }
|
| static const sqlite3_io_methods
|
| - *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
|
| + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl;
|
|
|
| -#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
|
| +#endif /* OS_VXWORKS */
|
|
|
| /*
|
| ** An abstract type for a pointer to an IO method finder function:
|
| @@ -5316,7 +5268,7 @@ static int fillInUnixFile(
|
| ** the afpLockingContext.
|
| */
|
| afpLockingContext *pCtx;
|
| - pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
| + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
| if( pCtx==0 ){
|
| rc = SQLITE_NOMEM;
|
| }else{
|
| @@ -5346,7 +5298,7 @@ static int fillInUnixFile(
|
| int nFilename;
|
| assert( zFilename!=0 );
|
| nFilename = (int)strlen(zFilename) + 6;
|
| - zLockFile = (char *)sqlite3_malloc(nFilename);
|
| + zLockFile = (char *)sqlite3_malloc64(nFilename);
|
| if( zLockFile==0 ){
|
| rc = SQLITE_NOMEM;
|
| }else{
|
| @@ -5379,7 +5331,7 @@ static int fillInUnixFile(
|
| }
|
| #endif
|
|
|
| - pNew->lastErrno = 0;
|
| + storeLastErrno(pNew, 0);
|
| #if OS_VXWORKS
|
| if( rc!=SQLITE_OK ){
|
| if( h>=0 ) robust_close(pNew, h, __LINE__);
|
| @@ -5406,19 +5358,17 @@ static const char *unixTempFileDir(void){
|
| static const char *azDirs[] = {
|
| 0,
|
| 0,
|
| - 0,
|
| "/var/tmp",
|
| "/usr/tmp",
|
| "/tmp",
|
| - 0 /* List terminator */
|
| + "."
|
| };
|
| unsigned int i;
|
| struct stat buf;
|
| - const char *zDir = 0;
|
| + const char *zDir = sqlite3_temp_directory;
|
|
|
| - azDirs[0] = sqlite3_temp_directory;
|
| - if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
|
| - if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
|
| + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
|
| + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
|
| for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
|
| if( zDir==0 ) continue;
|
| if( osStat(zDir, &buf) ) continue;
|
| @@ -5435,12 +5385,8 @@ static const char *unixTempFileDir(void){
|
| ** pVfs->mxPathname bytes.
|
| */
|
| static int unixGetTempname(int nBuf, char *zBuf){
|
| - static const unsigned char zChars[] =
|
| - "abcdefghijklmnopqrstuvwxyz"
|
| - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
| - "0123456789";
|
| - unsigned int i, j;
|
| const char *zDir;
|
| + int iLimit = 0;
|
|
|
| /* It's odd to simulate an io-error here, but really this is just
|
| ** using the io-error infrastructure to test that SQLite handles this
|
| @@ -5449,24 +5395,14 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
| SimulateIOError( return SQLITE_IOERR );
|
|
|
| zDir = unixTempFileDir();
|
| - if( zDir==0 ) zDir = ".";
|
| -
|
| - /* Check that the output buffer is large enough for the temporary file
|
| - ** name. If it is not, return SQLITE_ERROR.
|
| - */
|
| - if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
|
| - return SQLITE_ERROR;
|
| - }
|
| -
|
| do{
|
| - sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
|
| - j = (int)strlen(zBuf);
|
| - sqlite3_randomness(15, &zBuf[j]);
|
| - for(i=0; i<15; i++, j++){
|
| - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
| - }
|
| - zBuf[j] = 0;
|
| - zBuf[j+1] = 0;
|
| + u64 r;
|
| + sqlite3_randomness(sizeof(r), &r);
|
| + assert( nBuf>2 );
|
| + zBuf[nBuf-2] = 0;
|
| + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
|
| + zDir, r, 0);
|
| + if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
|
| }while( osAccess(zBuf,0)==0 );
|
| return SQLITE_OK;
|
| }
|
| @@ -5588,16 +5524,19 @@ static int findCreateFileMode(
|
| ** used by the test_multiplex.c module.
|
| */
|
| nDb = sqlite3Strlen30(zPath) - 1;
|
| -#ifdef SQLITE_ENABLE_8_3_NAMES
|
| - while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
|
| - if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
|
| -#else
|
| while( zPath[nDb]!='-' ){
|
| +#ifndef SQLITE_ENABLE_8_3_NAMES
|
| + /* In the normal case (8+3 filenames disabled) the journal filename
|
| + ** is guaranteed to contain a '-' character. */
|
| assert( nDb>0 );
|
| - assert( zPath[nDb]!='\n' );
|
| + assert( sqlite3Isalnum(zPath[nDb]) );
|
| +#else
|
| + /* If 8+3 names are possible, then the journal file might not contain
|
| + ** a '-' character. So check for that case and return early. */
|
| + if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
|
| +#endif
|
| nDb--;
|
| }
|
| -#endif
|
| memcpy(zDb, zPath, nDb);
|
| zDb[nDb] = '\0';
|
|
|
| @@ -5710,8 +5649,8 @@ static int unixOpen(
|
| ** the same instant might all reset the PRNG. But multiple resets
|
| ** are harmless.
|
| */
|
| - if( randomnessPid!=getpid() ){
|
| - randomnessPid = getpid();
|
| + if( randomnessPid!=osGetpid(0) ){
|
| + randomnessPid = osGetpid(0);
|
| sqlite3_randomness(0,0);
|
| }
|
|
|
| @@ -5723,7 +5662,7 @@ static int unixOpen(
|
| if( pUnused ){
|
| fd = pUnused->fd;
|
| }else{
|
| - pUnused = sqlite3_malloc(sizeof(*pUnused));
|
| + pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
| if( !pUnused ){
|
| return SQLITE_NOMEM;
|
| }
|
| @@ -5738,7 +5677,7 @@ static int unixOpen(
|
| }else if( !zName ){
|
| /* If zName is NULL, the upper layer is requesting a temp file. */
|
| assert(isDelete && !syncDir);
|
| - rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
|
| + rc = unixGetTempname(pVfs->mxPathname, zTmpname);
|
| if( rc!=SQLITE_OK ){
|
| return rc;
|
| }
|
| @@ -5771,7 +5710,8 @@ static int unixOpen(
|
| }
|
| fd = robust_open(zName, openFlags, openMode);
|
| OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
|
| - if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
| + assert( !isExclusive || (openFlags & O_CREAT)!=0 );
|
| + if( fd<0 && errno!=EISDIR && isReadWrite ){
|
| /* Failed to open the file for read/write access. Try read-only. */
|
| flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
| openFlags &= ~(O_RDWR|O_CREAT);
|
| @@ -5790,7 +5730,7 @@ static int unixOpen(
|
| ** the same as the original database.
|
| */
|
| if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
|
| - osFchown(fd, uid, gid);
|
| + robustFchown(fd, uid, gid);
|
| }
|
| }
|
| assert( fd>=0 );
|
| @@ -5827,13 +5767,16 @@ static int unixOpen(
|
|
|
| #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
|
| if( fstatfs(fd, &fsInfo) == -1 ){
|
| - ((unixFile*)pFile)->lastErrno = errno;
|
| + storeLastErrno(p, errno);
|
| robust_close(p, fd, __LINE__);
|
| return SQLITE_IOERR_ACCESS;
|
| }
|
| if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
|
| ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
|
| }
|
| + if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
|
| + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
|
| + }
|
| #endif
|
|
|
| /* Set up appropriate ctrlFlags */
|
| @@ -5856,19 +5799,6 @@ static int unixOpen(
|
| if( envforce!=NULL ){
|
| useProxy = atoi(envforce)>0;
|
| }else{
|
| - if( statfs(zPath, &fsInfo) == -1 ){
|
| - /* In theory, the close(fd) call is sub-optimal. If the file opened
|
| - ** with fd is a database file, and there are other connections open
|
| - ** on that file that are currently holding advisory locks on it,
|
| - ** then the call to close() will cancel those locks. In practice,
|
| - ** we're assuming that statfs() doesn't fail very often. At least
|
| - ** not while other file descriptors opened by the same process on
|
| - ** the same file are working. */
|
| - p->lastErrno = errno;
|
| - robust_close(p, fd, __LINE__);
|
| - rc = SQLITE_IOERR_ACCESS;
|
| - goto open_finished;
|
| - }
|
| useProxy = !(fsInfo.f_flags&MNT_LOCAL);
|
| }
|
| if( useProxy ){
|
| @@ -5937,7 +5867,8 @@ static int unixDelete(
|
| rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
|
| }
|
| robust_close(0, fd, __LINE__);
|
| - }else if( rc==SQLITE_CANTOPEN ){
|
| + }else{
|
| + assert( rc==SQLITE_CANTOPEN );
|
| rc = SQLITE_OK;
|
| }
|
| }
|
| @@ -5961,29 +5892,19 @@ static int unixAccess(
|
| int flags, /* What do we want to learn about the zPath file? */
|
| int *pResOut /* Write result boolean here */
|
| ){
|
| - int amode = 0;
|
| UNUSED_PARAMETER(NotUsed);
|
| SimulateIOError( return SQLITE_IOERR_ACCESS; );
|
| - switch( flags ){
|
| - case SQLITE_ACCESS_EXISTS:
|
| - amode = F_OK;
|
| - break;
|
| - case SQLITE_ACCESS_READWRITE:
|
| - amode = W_OK|R_OK;
|
| - break;
|
| - case SQLITE_ACCESS_READ:
|
| - amode = R_OK;
|
| - break;
|
| + assert( pResOut!=0 );
|
|
|
| - default:
|
| - assert(!"Invalid flags argument");
|
| - }
|
| - *pResOut = (osAccess(zPath, amode)==0);
|
| - if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
|
| + /* The spec says there are three possible values for flags. But only
|
| + ** two of them are actually used */
|
| + assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
|
| +
|
| + if( flags==SQLITE_ACCESS_EXISTS ){
|
| struct stat buf;
|
| - if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
|
| - *pResOut = 0;
|
| - }
|
| + *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
|
| + }else{
|
| + *pResOut = osAccess(zPath, W_OK|R_OK)==0;
|
| }
|
| return SQLITE_OK;
|
| }
|
| @@ -6004,6 +5925,7 @@ static int unixFullPathname(
|
| int nOut, /* Size of output buffer in bytes */
|
| char *zOut /* Output buffer */
|
| ){
|
| + int nByte;
|
|
|
| /* It's odd to simulate an io-error here, but really this is just
|
| ** using the io-error infrastructure to test that SQLite handles this
|
| @@ -6015,17 +5937,54 @@ static int unixFullPathname(
|
| assert( pVfs->mxPathname==MAX_PATHNAME );
|
| UNUSED_PARAMETER(pVfs);
|
|
|
| - zOut[nOut-1] = '\0';
|
| - if( zPath[0]=='/' ){
|
| + /* Attempt to resolve the path as if it were a symbolic link. If it is
|
| + ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
|
| + ** the identified file is not a symbolic link or does not exist, then
|
| + ** zPath is copied directly into zOut. Either way, nByte is left set to
|
| + ** the size of the string copied into zOut[] in bytes. */
|
| + nByte = osReadlink(zPath, zOut, nOut-1);
|
| + if( nByte<0 ){
|
| + if( errno!=EINVAL && errno!=ENOENT ){
|
| + return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
|
| + }
|
| sqlite3_snprintf(nOut, zOut, "%s", zPath);
|
| + nByte = sqlite3Strlen30(zOut);
|
| }else{
|
| + zOut[nByte] = '\0';
|
| + }
|
| +
|
| + /* If buffer zOut[] now contains an absolute path there is nothing more
|
| + ** to do. If it contains a relative path, do the following:
|
| + **
|
| + ** * move the relative path string so that it is at the end of th
|
| + ** zOut[] buffer.
|
| + ** * Call getcwd() to read the path of the current working directory
|
| + ** into the start of the zOut[] buffer.
|
| + ** * Append a '/' character to the cwd string and move the
|
| + ** relative path back within the buffer so that it immediately
|
| + ** follows the '/'.
|
| + **
|
| + ** This code is written so that if the combination of the CWD and relative
|
| + ** path are larger than the allocated size of zOut[] the CWD is silently
|
| + ** truncated to make it fit. This is Ok, as SQLite refuses to open any
|
| + ** file for which this function returns a full path larger than (nOut-8)
|
| + ** bytes in size. */
|
| + testcase( nByte==nOut-5 );
|
| + testcase( nByte==nOut-4 );
|
| + if( zOut[0]!='/' && nByte<nOut-4 ){
|
| int nCwd;
|
| - if( osGetcwd(zOut, nOut-1)==0 ){
|
| + int nRem = nOut-nByte-1;
|
| + memmove(&zOut[nRem], zOut, nByte+1);
|
| + zOut[nRem-1] = '\0';
|
| + if( osGetcwd(zOut, nRem-1)==0 ){
|
| return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
|
| }
|
| - nCwd = (int)strlen(zOut);
|
| - sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
|
| + nCwd = sqlite3Strlen30(zOut);
|
| + assert( nCwd<=nRem-1 );
|
| + zOut[nCwd] = '/';
|
| + memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
|
| }
|
| +
|
| return SQLITE_OK;
|
| }
|
|
|
| @@ -6112,8 +6071,8 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
| ** tests repeatable.
|
| */
|
| memset(zBuf, 0, nBuf);
|
| - randomnessPid = getpid();
|
| -#if !defined(SQLITE_TEST)
|
| + randomnessPid = osGetpid(0);
|
| +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
|
| {
|
| int fd, got;
|
| fd = robust_open("/dev/urandom", O_RDONLY, 0);
|
| @@ -6195,11 +6154,8 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
|
| *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
|
| #else
|
| struct timeval sNow;
|
| - if( gettimeofday(&sNow, 0)==0 ){
|
| - *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
|
| - }else{
|
| - rc = SQLITE_ERROR;
|
| - }
|
| + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */
|
| + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
|
| #endif
|
|
|
| #ifdef SQLITE_TEST
|
| @@ -6211,6 +6167,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
|
| return rc;
|
| }
|
|
|
| +#if 0 /* Not used */
|
| /*
|
| ** Find the current time (in Universal Coordinated Time). Write the
|
| ** current time and date as a Julian Day number into *prNow and
|
| @@ -6224,7 +6181,11 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
|
| *prNow = i/86400000.0;
|
| return rc;
|
| }
|
| +#else
|
| +# define unixCurrentTime 0
|
| +#endif
|
|
|
| +#if 0 /* Not used */
|
| /*
|
| ** We added the xGetLastError() method with the intention of providing
|
| ** better low-level error messages when operating-system problems come up
|
| @@ -6238,6 +6199,9 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
| UNUSED_PARAMETER(NotUsed3);
|
| return 0;
|
| }
|
| +#else
|
| +# define unixGetLastError 0
|
| +#endif
|
|
|
|
|
| /*
|
| @@ -6294,9 +6258,10 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
| **
|
| ** C APIs
|
| **
|
| -** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
|
| +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE,
|
| ** <proxy_path> | ":auto:");
|
| -** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
|
| +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE,
|
| +** &<proxy_path>);
|
| **
|
| **
|
| ** SQL pragmas
|
| @@ -6389,7 +6354,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
|
| ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
|
| ** force proxy locking to be used for every database file opened, and 0
|
| ** will force automatic proxy locking to be disabled for all database
|
| -** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or
|
| +** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or
|
| ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
|
| */
|
|
|
| @@ -6410,6 +6375,7 @@ struct proxyLockingContext {
|
| char *lockProxyPath; /* Name of the proxy lock file */
|
| char *dbPath; /* Name of the open file */
|
| int conchHeld; /* 1 if the conch is held, -1 if lockless */
|
| + int nFails; /* Number of conch taking failures */
|
| void *oldLockingContext; /* Original lockingcontext to restore on close */
|
| sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
|
| };
|
| @@ -6431,7 +6397,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
| {
|
| if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
|
| OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n",
|
| - lPath, errno, getpid()));
|
| + lPath, errno, osGetpid(0)));
|
| return SQLITE_IOERR_LOCK;
|
| }
|
| len = strlcat(lPath, "sqliteplocks", maxLen);
|
| @@ -6453,7 +6419,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
|
| }
|
| lPath[i+len]='\0';
|
| strlcat(lPath, ":auto:", maxLen);
|
| - OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()));
|
| + OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid(0)));
|
| return SQLITE_OK;
|
| }
|
|
|
| @@ -6480,7 +6446,7 @@ static int proxyCreateLockPath(const char *lockPath){
|
| if( err!=EEXIST ) {
|
| OSTRACE(("CREATELOCKPATH FAILED creating %s, "
|
| "'%s' proxy lock path=%s pid=%d\n",
|
| - buf, strerror(err), lockPath, getpid()));
|
| + buf, strerror(err), lockPath, osGetpid(0)));
|
| return err;
|
| }
|
| }
|
| @@ -6489,7 +6455,7 @@ static int proxyCreateLockPath(const char *lockPath){
|
| }
|
| buf[i] = lockPath[i];
|
| }
|
| - OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()));
|
| + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0)));
|
| return 0;
|
| }
|
|
|
| @@ -6523,7 +6489,7 @@ static int proxyCreateUnixFile(
|
| if( pUnused ){
|
| fd = pUnused->fd;
|
| }else{
|
| - pUnused = sqlite3_malloc(sizeof(*pUnused));
|
| + pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
| if( !pUnused ){
|
| return SQLITE_NOMEM;
|
| }
|
| @@ -6556,7 +6522,7 @@ static int proxyCreateUnixFile(
|
| }
|
| }
|
|
|
| - pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
|
| + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
|
| if( pNew==NULL ){
|
| rc = SQLITE_NOMEM;
|
| goto end_create_proxy;
|
| @@ -6589,8 +6555,10 @@ int sqlite3_hostid_num = 0;
|
|
|
| #define PROXY_HOSTIDLEN 16 /* conch file host id length */
|
|
|
| +#ifdef HAVE_GETHOSTUUID
|
| /* Not always defined in the headers as it ought to be */
|
| extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
| +#endif
|
|
|
| /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
|
| ** bytes of writable memory.
|
| @@ -6598,10 +6566,9 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
| static int proxyGetHostID(unsigned char *pHostID, int *pError){
|
| assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
|
| memset(pHostID, 0, PROXY_HOSTIDLEN);
|
| -#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
|
| - && __MAC_OS_X_VERSION_MIN_REQUIRED<1050
|
| +#ifdef HAVE_GETHOSTUUID
|
| {
|
| - static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
| + struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
| if( gethostuuid(pHostID, &timeout) ){
|
| int err = errno;
|
| if( pError ){
|
| @@ -6716,7 +6683,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
| */
|
| struct stat buf;
|
| if( osFstat(conchFile->h, &buf) ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return SQLITE_IOERR_LOCK;
|
| }
|
|
|
| @@ -6736,7 +6703,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
| char tBuf[PROXY_MAXCONCHLEN];
|
| int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
|
| if( len<0 ){
|
| - pFile->lastErrno = errno;
|
| + storeLastErrno(pFile, errno);
|
| return SQLITE_IOERR_LOCK;
|
| }
|
| if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
|
| @@ -6756,7 +6723,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
| if( 0==proxyBreakConchLock(pFile, myHostID) ){
|
| rc = SQLITE_OK;
|
| if( lockType==EXCLUSIVE_LOCK ){
|
| - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
|
| + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
|
| }
|
| if( !rc ){
|
| rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
|
| @@ -6794,11 +6761,12 @@ static int proxyTakeConch(unixFile *pFile){
|
| int forceNewLockPath = 0;
|
|
|
| OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h,
|
| - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
|
| + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
|
| + osGetpid(0)));
|
|
|
| rc = proxyGetHostID(myHostID, &pError);
|
| if( (rc&0xff)==SQLITE_IOERR ){
|
| - pFile->lastErrno = pError;
|
| + storeLastErrno(pFile, pError);
|
| goto end_takeconch;
|
| }
|
| rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
|
| @@ -6809,7 +6777,7 @@ static int proxyTakeConch(unixFile *pFile){
|
| readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
|
| if( readLen<0 ){
|
| /* I/O error: lastErrno set by seekAndRead */
|
| - pFile->lastErrno = conchFile->lastErrno;
|
| + storeLastErrno(pFile, conchFile->lastErrno);
|
| rc = SQLITE_IOERR_READ;
|
| goto end_takeconch;
|
| }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) ||
|
| @@ -6882,7 +6850,7 @@ static int proxyTakeConch(unixFile *pFile){
|
| rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
|
| }
|
| }else{
|
| - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
|
| + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
|
| }
|
| if( rc==SQLITE_OK ){
|
| char writeBuffer[PROXY_MAXCONCHLEN];
|
| @@ -6891,7 +6859,8 @@ static int proxyTakeConch(unixFile *pFile){
|
| writeBuffer[0] = (char)PROXY_CONCHVERSION;
|
| memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
|
| if( pCtx->lockProxyPath!=NULL ){
|
| - strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
|
| + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath,
|
| + MAXPATHLEN);
|
| }else{
|
| strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
|
| }
|
| @@ -7003,7 +6972,7 @@ static int proxyReleaseConch(unixFile *pFile){
|
| conchFile = pCtx->conchFile;
|
| OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
|
| (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
|
| - getpid()));
|
| + osGetpid(0)));
|
| if( pCtx->conchHeld>0 ){
|
| rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
|
| }
|
| @@ -7015,7 +6984,7 @@ static int proxyReleaseConch(unixFile *pFile){
|
|
|
| /*
|
| ** Given the name of a database file, compute the name of its conch file.
|
| -** Store the conch filename in memory obtained from sqlite3_malloc().
|
| +** Store the conch filename in memory obtained from sqlite3_malloc64().
|
| ** Make *pConchPath point to the new name. Return SQLITE_OK on success
|
| ** or SQLITE_NOMEM if unable to obtain memory.
|
| **
|
| @@ -7031,7 +7000,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
|
|
|
| /* Allocate space for the conch filename and initialize the name to
|
| ** the name of the original database file. */
|
| - *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
|
| + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
|
| if( conchPath==0 ){
|
| return SQLITE_NOMEM;
|
| }
|
| @@ -7103,7 +7072,8 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
|
| /* afp style keeps a reference to the db path in the filePath field
|
| ** of the struct */
|
| assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
|
| - strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN);
|
| + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
|
| + MAXPATHLEN);
|
| } else
|
| #endif
|
| if( pFile->pMethod == &dotlockIoMethods ){
|
| @@ -7144,9 +7114,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
| }
|
|
|
| OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
|
| - (lockPath ? lockPath : ":auto:"), getpid()));
|
| + (lockPath ? lockPath : ":auto:"), osGetpid(0)));
|
|
|
| - pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
| + pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
| if( pCtx==0 ){
|
| return SQLITE_NOMEM;
|
| }
|
| @@ -7216,7 +7186,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
| */
|
| static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
| switch( op ){
|
| - case SQLITE_GET_LOCKPROXYFILE: {
|
| + case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
|
| unixFile *pFile = (unixFile*)id;
|
| if( pFile->pMethod == &proxyIoMethods ){
|
| proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
|
| @@ -7231,13 +7201,16 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
| }
|
| return SQLITE_OK;
|
| }
|
| - case SQLITE_SET_LOCKPROXYFILE: {
|
| + case SQLITE_FCNTL_SET_LOCKPROXYFILE: {
|
| unixFile *pFile = (unixFile*)id;
|
| int rc = SQLITE_OK;
|
| int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
|
| if( pArg==NULL || (const char *)pArg==0 ){
|
| if( isProxyStyle ){
|
| - /* turn off proxy locking - not supported */
|
| + /* turn off proxy locking - not supported. If support is added for
|
| + ** switching proxy locking mode off then it will need to fail if
|
| + ** the journal mode is WAL mode.
|
| + */
|
| rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
|
| }else{
|
| /* turn off proxy locking - already off - NOOP */
|
| @@ -7367,7 +7340,7 @@ static int proxyUnlock(sqlite3_file *id, int eFileLock) {
|
| ** Close a file that uses proxy locks.
|
| */
|
| static int proxyClose(sqlite3_file *id) {
|
| - if( id ){
|
| + if( ALWAYS(id) ){
|
| unixFile *pFile = (unixFile*)id;
|
| proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
|
| unixFile *lockProxy = pCtx->lockProxy;
|
| @@ -7482,8 +7455,10 @@ int sqlite3_os_init(void){
|
| ** array cannot be const.
|
| */
|
| static sqlite3_vfs aVfs[] = {
|
| -#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
|
| +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
| UNIXVFS("unix", autolockIoFinder ),
|
| +#elif OS_VXWORKS
|
| + UNIXVFS("unix", vxworksIoFinder ),
|
| #else
|
| UNIXVFS("unix", posixIoFinder ),
|
| #endif
|
| @@ -7493,11 +7468,11 @@ int sqlite3_os_init(void){
|
| #if OS_VXWORKS
|
| UNIXVFS("unix-namedsem", semIoFinder ),
|
| #endif
|
| -#if SQLITE_ENABLE_LOCKING_STYLE
|
| +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
|
| UNIXVFS("unix-posix", posixIoFinder ),
|
| -#if !OS_VXWORKS
|
| - UNIXVFS("unix-flock", flockIoFinder ),
|
| #endif
|
| +#if SQLITE_ENABLE_LOCKING_STYLE
|
| + UNIXVFS("unix-flock", flockIoFinder ),
|
| #endif
|
| #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
| UNIXVFS("unix-afp", afpIoFinder ),
|
| @@ -7509,7 +7484,7 @@ int sqlite3_os_init(void){
|
|
|
| /* Double-check that the aSyscall[] array has been constructed
|
| ** correctly. See ticket [bb3a86e890c8e96ab] */
|
| - assert( ArraySize(aSyscall)==25 );
|
| + assert( ArraySize(aSyscall)==27 );
|
|
|
| /* Register all VFSes defined in the aVfs[] array */
|
| for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
|
|