Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Continuing work on the os_unix.c refactoring. Removed all of the LOCKING_STYLE_* constants and instead pass around pointers to the underlying sqlite3_io_method objects. (CVS 5966) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1017d2fb1935a278ef442030bf7bdf5e |
User & Date: | drh 2008-11-29 00:56:53.000 |
Context
2008-11-29
| ||
02:20 | Continuing to refactor os_unix.c. This is an incremental check-in. (CVS 5967) (check-in: c13df0311e user: drh tags: trunk) | |
00:56 | Continuing work on the os_unix.c refactoring. Removed all of the LOCKING_STYLE_* constants and instead pass around pointers to the underlying sqlite3_io_method objects. (CVS 5966) (check-in: 1017d2fb19 user: drh tags: trunk) | |
2008-11-28
| ||
15:37 | First step in refactoring os_unix.c. This is work in progress. The code compiles and runs on Linux and MacOSX (as long as SQLITE_ENABLE_LOCKING_STYLE is turned off), but there are a few test failures. (CVS 5965) (check-in: 7825cd63e5 user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
36 37 38 39 40 41 42 | ** + for named semaphore locks (VxWorks only) ** + for AFP filesystem locks (MacOSX only) ** + for proxy locks (MacOSX only) ** * The routine used to detect an appropriate locking style ** * sqlite3_file methods not associated with locking ** * Implementations of sqlite3_os_init() and sqlite3_os_end() ** | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | ** + for named semaphore locks (VxWorks only) ** + for AFP filesystem locks (MacOSX only) ** + for proxy locks (MacOSX only) ** * The routine used to detect an appropriate locking style ** * sqlite3_file methods not associated with locking ** * Implementations of sqlite3_os_init() and sqlite3_os_end() ** ** $Id: os_unix.c,v 1.223 2008/11/29 00:56:53 drh Exp $ */ #include "sqliteInt.h" #if SQLITE_OS_UNIX /* This file is used on unix only */ /* ** This module implements the following locking styles: ** |
︙ | ︙ | |||
152 153 154 155 156 157 158 | #endif /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | #endif /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 /* ** 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 */ #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) |
︙ | ︙ | |||
858 859 860 861 862 863 864 | ** On anything other than linux, assume threads override each others locks. */ static void testThreadLockingBehavior(int fd_orig){ UNUSED_PARAMETER(fd_orig); threadsOverrideEachOthersLocks = 1; } #endif /* SQLITE_THERADSAFE && defined(__linux__) */ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 | ** On anything other than linux, assume threads override each others locks. */ static void testThreadLockingBehavior(int fd_orig){ UNUSED_PARAMETER(fd_orig); threadsOverrideEachOthersLocks = 1; } #endif /* SQLITE_THERADSAFE && defined(__linux__) */ /* ** Release a unixLockInfo structure previously allocated by findLockInfo(). */ static void releaseLockInfo(struct unixLockInfo *pLock){ if( pLock ){ pLock->nRef--; |
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 | *ppOpen = pOpen; } exit_findlockinfo: return rc; } /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut ** 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. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 | *ppOpen = pOpen; } exit_findlockinfo: return rc; } /* ** If we are currently in a different thread than the thread that the ** unixFile argument belongs to, then transfer ownership of the unixFile ** over to the current thread. ** ** A unixFile is only owned by a thread on systems that use LinuxThreads. ** ** Ownership transfer is only allowed if the unixFile is currently unlocked. ** If the unixFile is locked and an ownership is wrong, then return ** SQLITE_MISUSE. SQLITE_OK is returned if everything works. */ #if SQLITE_THREADSAFE && defined(__linux__) static int transferOwnership(unixFile *pFile){ int rc; pthread_t hSelf; if( threadsOverrideEachOthersLocks ){ /* Ownership transfers not needed on this system */ return SQLITE_OK; } hSelf = pthread_self(); if( pthread_equal(pFile->tid, hSelf) ){ /* We are still in the same thread */ OSTRACE1("No-transfer, same thread\n"); return SQLITE_OK; } if( pFile->locktype!=NO_LOCK ){ /* We cannot change ownership while we are holding a lock! */ return SQLITE_MISUSE; } OSTRACE4("Transfer ownership of %d from %d to %d\n", pFile->h, pFile->tid, hSelf); pFile->tid = hSelf; if (pFile->pLock != NULL) { releaseLockInfo(pFile->pLock); rc = findLockInfo(pFile, &pFile->pLock, 0); OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, locktypeName(pFile->locktype), locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); return rc; } else { return SQLITE_OK; } } #else /* if not SQLITE_THREADSAFE */ /* On single-threaded builds, ownership transfer is a no-op */ # define transferOwnership(X) SQLITE_OK #endif /* SQLITE_THREADSAFE */ /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut ** 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. */ |
︙ | ︙ | |||
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 | ** connections from reading or writing the database. ** ** (2) An application crash or power loss can leave stale lock files ** sitting around that need to be cleared manually. ** ** Nevertheless, a dotlock is an appropriate locking mode for use if no ** other locking strategy is available. */ /* ** The file suffix added to the data base filename in order to create the ** lock file. */ #define DOTLOCK_SUFFIX ".lock" | > > > > > > > > > | > > | > > < < | < < < < | < < | | < < < < > | > | < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > | | < < < < < < < < | < < > > > > > > > > > | | > > | | > | | | 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 | ** connections from reading or writing the database. ** ** (2) An application crash or power loss can leave stale lock files ** sitting around that need to be cleared manually. ** ** Nevertheless, a dotlock is an appropriate locking mode for use if no ** other locking strategy is available. ** ** Dotfile locking works by creating a file in the same directory as the ** database and with the same name but with a ".lock" extension added. ** The existance of a lock file implies an EXCLUSIVE lock. All other lock ** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. */ /* ** The file suffix added to the data base filename in order to create the ** lock file. */ #define DOTLOCK_SUFFIX ".lock" /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut ** 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. ** ** In dotfile locking, either a lock exists or it does not. So in this ** variation of CheckReservedLock(), *pResOut is set to true if any lock ** is held on the file and false if the file is unlocked. */ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); /* Check if a thread in this process holds such a lock */ if( pFile->locktype>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 = access(zLockFile, 0)==0; } OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved); *pResOut = reserved; return rc; } /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: ** ** (1) SHARED_LOCK ** (2) RESERVED_LOCK ** (3) PENDING_LOCK ** (4) EXCLUSIVE_LOCK ** ** Sometimes when requesting one lock state, additional lock states ** are inserted in between. The locking might fail on one of the later ** transitions leaving the lock state different from what it started but ** still short of its goal. The following chart shows the allowed ** transitions and the inserted intermediate states: ** ** UNLOCKED -> SHARED ** SHARED -> RESERVED ** SHARED -> (PENDING) -> EXCLUSIVE ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. ** ** With dotfile locking, we really only support state (4): EXCLUSIVE. ** But we track the other locking levels internally. */ static int dotlockLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; int fd; char *zLockFile = (char *)pFile->lockingContext; int rc = SQLITE_OK; /* If we have any lock, then the lock file already exists. All we have ** to do is adjust our internal record of the lock level. */ if( pFile->locktype > NO_LOCK ){ pFile->locktype = locktype; #if !OS_VXWORKS /* Always update the timestamp on the old file */ utimes(zLockFile, NULL); #endif return SQLITE_OK; } /* grab an exclusive lock */ fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ int tErrno = errno; if( EEXIST == tErrno ){ rc = SQLITE_BUSY; } else { rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } } return rc; } if( close(fd) ){ pFile->lastErrno = errno; rc = SQLITE_IOERR_CLOSE; } /* got it, set the type and return ok */ pFile->locktype = locktype; return rc; } /* ** Lower the locking level on file descriptor pFile to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** ** When the locking level reaches NO_LOCK, delete the lock file. */ static int dotlockUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; assert( pFile ); OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype, pFile->locktype, getpid()); assert( locktype<=SHARED_LOCK ); /* no-op if possible */ if( pFile->locktype==locktype ){ return SQLITE_OK; } /* To downgrade to shared, simply update our internal notion of the ** lock state. No need to mess with the file on disk. */ if( locktype==SHARED_LOCK ){ pFile->locktype = SHARED_LOCK; return SQLITE_OK; } /* To fully unlock the database, delete the lock file */ assert( locktype==NO_LOCK ); if( unlink(zLockFile) ){ int rc, tErrno = errno; if( ENOENT != tErrno ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } |
︙ | ︙ | |||
1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 | ** ** Use the flock() system call to do file locking. ** ** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if ** compiling for VXWORKS. */ #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS /* ** The flockLockingContext is not used */ typedef void flockLockingContext; /* flock-style reserved lock checking following the behavior of | > | 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 | ** ** Use the flock() system call to do file locking. ** ** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if ** compiling for VXWORKS. */ #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS #include <sys/file.h> /* ** The flockLockingContext is not used */ typedef void flockLockingContext; /* flock-style reserved lock checking following the behavior of |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ *pResOut = reserved; return rc; } static int flockLock(sqlite3_file *id, int locktype) { int rc = SQLITE_OK; | < | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ *pResOut = reserved; return rc; } static int flockLock(sqlite3_file *id, int locktype) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; assert( pFile ); /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ if (pFile->locktype > NO_LOCK) { |
︙ | ︙ | |||
2625 2626 2627 2628 2629 2630 2631 | ** Proxy locking is only available on MacOSX */ #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); static int getLockPath(const char *dbPath, char *lPath, size_t maxLen); | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 | ** Proxy locking is only available on MacOSX */ #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); static int getLockPath(const char *dbPath, char *lPath, size_t maxLen); static int createProxyUnixFile(const char *path, unixFile **ppFile); static int fillInUnixFile(sqlite3_vfs *pVfs, int h, int dirfd, sqlite3_file *pId, const char *zFilename, int noLock, int isDelete); static int takeConch(unixFile *pFile); static int releaseConch(unixFile *pFile); static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf); #ifdef SQLITE_TEST /* simulate multiple hosts by creating unique hostid file paths */ int sqlite3_hostid_num = 0; #endif /* |
︙ | ︙ | |||
3018 3019 3020 3021 3022 3023 3024 | rc = createProxyUnixFile(path, &pCtx->lockProxy); } if( rc==SQLITE_OK ){ pCtx->conchHeld = 1; if( tLockPath ){ pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath); | | < | 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 | rc = createProxyUnixFile(path, &pCtx->lockProxy); } if( rc==SQLITE_OK ){ pCtx->conchHeld = 1; if( tLockPath ){ pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath); if( pCtx->lockProxy->pMethod == &afpIoMethods ){ ((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath = pCtx->lockProxyPath; } } } else { conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } |
︙ | ︙ | |||
3208 3209 3210 3211 3212 3213 3214 | /* all memory is allocated, proxys are created and assigned, ** switch the locking context and pMethod then return. */ pCtx->dbPath = sqlite3DbStrDup(0, dbPath); pCtx->oldLockingContext = pFile->lockingContext; pFile->lockingContext = pCtx; pCtx->pOldMethod = pFile->pMethod; | | | 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 | /* all memory is allocated, proxys are created and assigned, ** switch the locking context and pMethod then return. */ pCtx->dbPath = sqlite3DbStrDup(0, dbPath); pCtx->oldLockingContext = pFile->lockingContext; pFile->lockingContext = pCtx; pCtx->pOldMethod = pFile->pMethod; pFile->pMethod = &proxyIoMethods; }else{ if( pCtx->conchFile ){ rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); if( rc ) return rc; sqlite3_free(pCtx->conchFile); } sqlite3_free(pCtx->conchFilePath); |
︙ | ︙ | |||
3642 3643 3644 3645 3646 3647 3648 | */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; } | | > > > | > | < < < < | | | > > | > | < < < < < < < | | 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 | */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; } case SQLITE_LAST_ERRNO: { *(int*)pArg = ((unixFile*)id)->lastErrno; return SQLITE_OK; } #if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__) case SQLITE_GET_LOCKPROXYFILE: { unixFile *pFile = (unixFile*)id; if( pFile->pMethod == &proxyIoMethods ){ proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; takeConch(pFile); if( pCtx->lockProxyPath ){ *(const char **)pArg = pCtx->lockProxyPath; }else{ *(const char **)pArg = ":auto: (not held)"; } } else { *(const char **)pArg = NULL; } return SQLITE_OK; } case SQLITE_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 */ rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; }else{ /* turn off proxy locking - already off - NOOP */ rc = SQLITE_OK; } }else{ const char *proxyPath = (const char *)pArg; if( isProxyStyle ){ proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) ){ rc = SQLITE_OK; }else{ rc = switchLockProxyPath(pFile, proxyPath); } }else{ /* turn on proxy file locking */ rc = transformUnixFileForLockProxy(pFile, proxyPath); } } return rc; } #endif } return SQLITE_ERROR; } /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be |
︙ | ︙ | |||
3733 3734 3735 3736 3737 3738 3739 | /* ** Here ends the implementation of all sqlite3_file methods. ** ********************** End sqlite3_file Methods ******************************* ******************************************************************************/ /* | | > | > < | < | | > | | | | | | > > > > > > > > > > > > > > > > > > > > > | | | | > > > > > | > > > > > > | | > > > | > > > | > > | | > > | | | > > > > | > > | > > > > > > > | > > > > > > > | | > > > > > > > | > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | > | > > | > > | | > > > > | < | > > > > > > > > > > > > > > | | < > > | < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | < | > | | | | | | | | | | | | | | | | | | | | < | < < < < < < | < < < < > | > | < < | > | | < | | > | > | 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 | /* ** Here ends the implementation of all sqlite3_file methods. ** ********************** End sqlite3_file Methods ******************************* ******************************************************************************/ /* ** Each instance of this macro generates two objects: ** ** * A constant sqlite3_io_methods object call METHOD that has locking ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. ** ** * An I/O method finder function called FINDER that returns a pointer ** to the METHOD object in the previous bullet. */ #define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK) \ static const sqlite3_io_methods METHOD = { \ 1, /* iVersion */ \ CLOSE, /* xClose */ \ unixRead, /* xRead */ \ unixWrite, /* xWrite */ \ unixTruncate, /* xTruncate */ \ unixSync, /* xSync */ \ unixFileSize, /* xFileSize */ \ LOCK, /* xLock */ \ UNLOCK, /* xUnlock */ \ CKLOCK, /* xCheckReservedLock */ \ unixFileControl, /* xFileControl */ \ unixSectorSize, /* xSectorSize */ \ unixDeviceCharacteristics /* xDeviceCapabilities */ \ }; \ static const sqlite3_io_methods *FINDER(const char *z, int h){ \ UNUSED_PARAMETER(z); UNUSED_PARAMETER(h); \ return &METHOD; \ } /* ** Here are all of the sqlite3_io_methods objects for each of the ** locking strategies. Functions that return pointers to these methods ** are also created. */ IOMETHODS( posixIoFinder, /* Finder function name */ posixIoMethods, /* sqlite3_io_methods object name */ unixClose, /* xClose method */ unixLock, /* xLock method */ unixUnlock, /* xUnlock method */ unixCheckReservedLock /* xCheckReservedLock method */ ); IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ nolockCheckReservedLock /* xCheckReservedLock method */ ); IOMETHODS( dotlockIoFinder, /* Finder function name */ dotlockIoMethods, /* sqlite3_io_methods object name */ dotlockClose, /* xClose method */ dotlockLock, /* xLock method */ dotlockUnlock, /* xUnlock method */ dotlockCheckReservedLock /* xCheckReservedLock method */ ); #if SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( flockIoFinder, /* Finder function name */ flockIoMethods, /* sqlite3_io_methods object name */ flockClose, /* xClose method */ flockLock, /* xLock method */ flockUnlock, /* xUnlock method */ flockCheckReservedLock /* xCheckReservedLock method */ ); #endif #if OS_VXWORKS IOMETHODS( semIoFinder, /* Finder function name */ semIoMethods, /* sqlite3_io_methods object name */ semClose, /* xClose method */ semLock, /* xLock method */ semUnlock, /* xUnlock method */ semCheckReservedLock /* xCheckReservedLock method */ ); #endif #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( afpIoFinder, /* Finder function name */ afpIoMethods, /* sqlite3_io_methods object name */ afpClose, /* xClose method */ afpLock, /* xLock method */ afpUnlock, /* xUnlock method */ afpCheckReservedLock /* xCheckReservedLock method */ ); IOMETHODS( proxyIoFinder, /* Finder function name */ proxyIoMethods, /* sqlite3_io_methods object name */ proxyClose, /* xClose method */ proxyLock, /* xLock method */ proxyUnlock, /* xUnlock method */ proxyCheckReservedLock /* xCheckReservedLock method */ ); #endif #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE /* ** This procedure attempts to determine the best locking strategy for ** the given database file. It then returns the sqlite3_io_methods ** object that implements that strategy. ** ** This is for MacOSX only. */ static const sqlite3_io_methods *autolockIoFinder( const char *filePath, /* name of the database file */ int fd /* file descriptor open on the database file */ ){ static const struct Mapping { const char *zFilesystem; const sqlite3_io_methods *pMethods; } aMap[] = { { "hfs", &posixIoMethods }, { "ufs", &posixIoMethods }, { "afpfs", &afpIoMethods }, #ifdef SQLITE_ENABLE_AFP_LOCKING_SMB { "smbfs", &afpIoMethods }, #else { "smbfs", &flockIoMethods }, #endif { "webdav", &nolockIoMethods }, { 0, 0 } }; int i; struct statfs fsInfo; struct flock lockInfo; if( !filePath ){ return &nolockIoMethods; } if( statfs(filePath, &fsInfo) != -1 ){ if( fsInfo.f_flags & MNT_RDONLY ){ return &nolockIoMethods; } for(i=0; aMap[i].zFilesystem; i++){ if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ return aMap[i].pMethods; } } } /* Default case. Handles, amongst others, "nfs". ** Test byte-range lock using fcntl(). If the call succeeds, ** assume that the file-system supports POSIX style locks. */ lockInfo.l_len = 1; lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { return &posixIoMethods; }else{ return &dotlockIoMethods; } } #endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */ /* ** An abstract type for a pointer to a IO method finder function: */ typedef const sqlite3_io_methods *(*finder_type)(const char*,int); /**************************************************************************** **************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the ** sqlite3_vfs object. */ /* ** Initialize the contents of the unixFile structure pointed to by pId. */ static int fillInUnixFile( sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ int dirfd, /* Directory file descriptor */ sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename, /* Name of the file being opened */ int noLock, /* Omit locking if true */ int isDelete /* Delete on close if true */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; assert( pNew->pLock==NULL ); assert( pNew->pOpen==NULL ); /* Parameter isDelete is only used on vxworks. Parameter pVfs is only ** used if ENABLE_LOCKING_STYLE is defined. Express this explicitly ** here to prevent compiler warnings about unused parameters. */ #if !OS_VXWORKS UNUSED_PARAMETER(isDelete); #endif #if !SQLITE_ENABLE_LOCKING_STYLE UNUSED_PARAMETER(pVfs); #endif #if !OS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE UNUSED_PARAMETER(zFilename); #endif OSTRACE3("OPEN %-3d %s\n", h, zFilename); pNew->h = h; pNew->dirfd = dirfd; SET_THREADID(pNew); #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); if( pNew->pId==0 ){ noLock = 1; rc = SQLITE_NOMEM; } #endif if( noLock ){ pLockingStyle = &nolockIoMethods; }else{ pLockingStyle = (*(finder_type)pVfs->pAppData)(zFilename, h); #if SQLITE_ENABLE_LOCKING_STYLE /* Cache zFilename in the locking context (AFP and dotlock override) for ** proxyLock activation is possible (remote proxy is based on db name) ** zFilename remains valid until file is closed, to support */ pNew->lockingContext = (void*)zFilename; #endif } if( pLockingStyle == &posixIoMethods ){ unixEnterMutex(); rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); unixLeaveMutex(); } #if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__) else if( pLockingStyle == &apfIoMethods ){ /* AFP locking uses the file path so it needs to be included in ** the afpLockingContext. */ afpLockingContext *pCtx; pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) ); if( pCtx==0 ){ rc = SQLITE_NOMEM; }else{ /* NB: zFilename exists and remains valid until the file is closed ** according to requirement F11141. So we do not need to make a ** copy of the filename. */ pCtx->dbPath = zFilename; srandomdev(); unixEnterMutex(); rc = findLockInfo(pNew, NULL, &pNew->pOpen); unixLeaveMutex(); } } #endif #if SQLITE_ENABLE_LOCKING_STYLE else if( pLockingStyle == &dotlockIoMethods ){ /* Dotfile locking uses the file path so it needs to be included in ** the dotlockLockingContext */ char *zLockFile; int nFilename; nFilename = strlen(zFilename) + 6; zLockFile = (char *)sqlite3_malloc(nFilename); if( zLockFile==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); } pNew->lockingContext = zLockFile; } #endif #if OS_VXWORKS else if( pLockingStyle == &semIoMethods ){ /* Named semaphore locking uses the file path so it needs to be ** included in the semLockingContext */ unixEnterMutex(); rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){ char *zSemName = pNew->pOpen->aSemName; int n; sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem", pNew->pId->zCanonicalName); for( n=0; zSemName[n]; n++ ) if( zSemName[n]=='/' ) zSemName[n] = '_'; pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1); if( pNew->pOpen->pSem == SEM_FAILED ){ rc = SQLITE_NOMEM; pNew->pOpen->aSemName[0] = '\0'; } } unixLeaveMutex(); } #endif pNew->lastErrno = 0; #if OS_VXWORKS if( rc!=SQLITE_OK ){ unlink(zFilename); isDelete = 0; } pNew->isDelete = isDelete; #endif if( rc!=SQLITE_OK ){ if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */ close(h); }else{ pNew->pMethod = pLockingStyle; OpenCounter(+1); } return rc; } #if SQLITE_ENABLE_LOCKING_STYLE static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){ #if defined(__DARWIN__) if( pFile->pMethod == &afpIoMethods ){ /* afp style keeps a reference to the db path in the filePath field ** of the struct */ assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); strcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath) }else #endif if( pFile->pMethod == &dotlockIoMethods ){ /* dot lock style uses the locking context to store the dot lock ** file path */ int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); memcpy(dbPath, (char *)pFile->lockingContext, len + 1); }else{ /* all other styles use the locking context to store the db file path */ assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); strcpy(dbPath, (char *)pFile->lockingContext); } return SQLITE_OK; } #endif /* ** Open a file descriptor to the directory containing file zFilename. ** If successful, *pFd is set to the opened file descriptor and |
︙ | ︙ | |||
4279 4280 4281 4282 4283 4284 4285 | #if SQLITE_PREFER_PROXY_LOCKING if( zPath!=NULL && !noLock ){ char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, | | | | 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 | #if SQLITE_PREFER_PROXY_LOCKING if( zPath!=NULL && !noLock ){ char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, ** 0 means never use proxy, NULL means use proxy for non-local files only */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ struct statfs fsInfo; if( statfs(zPath, &fsInfo) == -1 ){ ((unixFile*)pFile)->lastErrno = errno; |
︙ | ︙ | |||
4591 4592 4593 4594 4595 4596 4597 | */ int sqlite3_os_init(void){ /* Macro to define the static contents of an sqlite3_vfs structure for ** the unix backend. The two parameters are the values to use for ** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively. ** */ | | | | | > | > | > | | | > | | | | 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 | */ int sqlite3_os_init(void){ /* Macro to define the static contents of an sqlite3_vfs structure for ** the unix backend. The two parameters are the values to use for ** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively. ** */ #define UNIXVFS(VFSNAME, FINDER) { \ 1, /* iVersion */ \ sizeof(unixFile), /* szOsFile */ \ MAX_PATHNAME, /* mxPathname */ \ 0, /* pNext */ \ VFSNAME, /* zName */ \ (void*)FINDER, /* pAppData */ \ unixOpen, /* xOpen */ \ unixDelete, /* xDelete */ \ unixAccess, /* xAccess */ \ unixFullPathname, /* xFullPathname */ \ unixDlOpen, /* xDlOpen */ \ unixDlError, /* xDlError */ \ unixDlSym, /* xDlSym */ \ unixDlClose, /* xDlClose */ \ unixRandomness, /* xRandomness */ \ unixSleep, /* xSleep */ \ unixCurrentTime, /* xCurrentTime */ \ unixGetLastError /* xGetLastError */ \ } unsigned int i; static sqlite3_vfs aVfs[] = { #if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__) UNIXVFS("unix", autolockIoFinder ), #else UNIXVFS("unix", posixIoFinder ), #endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif #if SQLITE_ENABLE_LOCKING_STYLE UNIXVFS("unix-posix", posixIoFinder ), UNIXVFS("unix-flock", flockIoFinder ), #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__) UNIXVFS("unix-afp", afpIoFinder ), UNIXVFS("unix-proxy", proxyIoFinder ), #endif }; for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } return SQLITE_OK; } |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.333 2008/11/29 00:56:53 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* |
︙ | ︙ | |||
4523 4524 4525 4526 4527 4528 4529 | if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " DB", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; | | | | > | > | > > | > > | > | > > | 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 | if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " DB", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__) { char *proxyPath = "test.proxy"; char *testPath; rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); if( rc ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; } rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath); if( strncmp(proxyPath,testPath,11) ) { Tcl_AppendResult(interp, "Lock proxy file did not match the " "previously assigned value", 0); return TCL_ERROR; } if( rc ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; } rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); if( rc ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; } } #endif return TCL_OK; } /* |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** ** This file contains code used for testing the SQLite system. ** None of the code in this file goes into a deliverable build. ** ** The focus of this file is providing the TCL testing layer ** access to compile-time constants. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This file contains code used for testing the SQLite system. ** None of the code in this file goes into a deliverable build. ** ** The focus of this file is providing the TCL testing layer ** access to compile-time constants. ** ** $Id: test_config.c,v 1.44 2008/11/29 00:56:54 drh Exp $ */ #include "sqliteLimit.h" #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
388 389 390 391 392 393 394 | #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif | | | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif #if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__) Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","0",TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_SHARED_CACHE Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "1", TCL_GLOBAL_ONLY); |
︙ | ︙ |