/ Check-in [1017d2fb]
Login

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1017d2fb1935a278ef442030bf7bdf5e112c566a
User & Date: drh 2008-11-29 00:56:53
Context
2008-11-29
02:20
Continuing to refactor os_unix.c. This is an incremental check-in. (CVS 5967) check-in: c13df031 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: 1017d2fb 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: 7825cd63 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

    36     36   **      + for named semaphore locks (VxWorks only)
    37     37   **      + for AFP filesystem locks (MacOSX only)
    38     38   **      + for proxy locks (MacOSX only)
    39     39   **   *  The routine used to detect an appropriate locking style
    40     40   **   *  sqlite3_file methods not associated with locking
    41     41   **   *  Implementations of sqlite3_os_init() and sqlite3_os_end()
    42     42   **
    43         -** $Id: os_unix.c,v 1.222 2008/11/28 15:37:20 drh Exp $
           43  +** $Id: os_unix.c,v 1.223 2008/11/29 00:56:53 drh Exp $
    44     44   */
    45     45   #include "sqliteInt.h"
    46     46   #if SQLITE_OS_UNIX              /* This file is used on unix only */
    47     47   
    48     48   /*
    49     49   ** This module implements the following locking styles:
    50     50   **
................................................................................
   152    152   #endif
   153    153   
   154    154   /*
   155    155   ** Maximum supported path-length.
   156    156   */
   157    157   #define MAX_PATHNAME 512
   158    158   
   159         -/*
   160         -** The locking styles are associated with the different file locking
   161         -** capabilities supported by different file systems.  
   162         -**
   163         -** POSIX     support for shared and exclusive byte-range locks 
   164         -**
   165         -** NONE      no locking will be attempted, this is only used for
   166         -**           read-only file systems currently
   167         -**
   168         -** DOTLOCK   isn't a true locking style, it refers to the use of a special
   169         -**           file named the same as the database file with a '.lock'
   170         -**           extension, this can be used on file systems that do not
   171         -**           offer any reliable file locking
   172         -**
   173         -** FLOCK     only a single file-global exclusive lock  (Not on VxWorks)
   174         -**
   175         -** NAMEDSEM  similar to DOTLOCK but uses a named semaphore instead of an
   176         -**           indicator file.  (VxWorks only)
   177         -**
   178         -** AFP       support exclusive byte-range locks  (MacOSX only)
   179         -**
   180         -** PROXY     uses a second file to represent the lock state of the database
   181         -**           file which is never actually locked, a third file controls
   182         -**           access to the proxy  (MacOSX only)
   183         -**
   184         -** Note that because FLOCK and NAMEDSEM are never used together, they
   185         -** share the same code number (3).  The locking mode numbering is 
   186         -** chosen so that a set of locking modes that are contiguous integers
   187         -** from 1 to N.  On generic unix systems without flock() support,
   188         -** the modes are 1..3.  On generic unix with flock() support, the modes
   189         -** are 1..4.  On VxWorks, the modes are 1..4.  On MacOSX the modes
   190         -** are 1..6.
   191         -*/
   192         -#define LOCKING_STYLE_POSIX        1
   193         -#define LOCKING_STYLE_NONE         2
   194         -#define LOCKING_STYLE_DOTFILE      3
   195         -#define LOCKING_STYLE_FLOCK        4
   196         -#define LOCKING_STYLE_NAMEDSEM     4
   197         -#define LOCKING_STYLE_AFP          5
   198         -#define LOCKING_STYLE_PROXY        6
   199         -
   200         -#define LOCKING_STYLE_AUTOMATIC    0  /* Choose lock style automatically */
   201         -
   202    159   /*
   203    160   ** Only set the lastErrno if the error code is a real error and not 
   204    161   ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
   205    162   */
   206    163   #define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
   207    164   
   208    165   
................................................................................
   858    815   ** On anything other than linux, assume threads override each others locks.
   859    816   */
   860    817   static void testThreadLockingBehavior(int fd_orig){
   861    818     UNUSED_PARAMETER(fd_orig);
   862    819     threadsOverrideEachOthersLocks = 1;
   863    820   }
   864    821   #endif /* SQLITE_THERADSAFE && defined(__linux__) */
   865         -
   866         -/*
   867         -** If we are currently in a different thread than the thread that the
   868         -** unixFile argument belongs to, then transfer ownership of the unixFile
   869         -** over to the current thread.
   870         -**
   871         -** A unixFile is only owned by a thread on systems where one thread is
   872         -** unable to override locks created by a different thread.  RedHat9 is
   873         -** an example of such a system.
   874         -**
   875         -** Ownership transfer is only allowed if the unixFile is currently unlocked.
   876         -** If the unixFile is locked and an ownership is wrong, then return
   877         -** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
   878         -*/
   879         -#if SQLITE_THREADSAFE && defined(__linux__)
   880         -static int transferOwnership(unixFile *pFile){
   881         -  int rc;
   882         -  pthread_t hSelf;
   883         -  if( threadsOverrideEachOthersLocks ){
   884         -    /* Ownership transfers not needed on this system */
   885         -    return SQLITE_OK;
   886         -  }
   887         -  hSelf = pthread_self();
   888         -  if( pthread_equal(pFile->tid, hSelf) ){
   889         -    /* We are still in the same thread */
   890         -    OSTRACE1("No-transfer, same thread\n");
   891         -    return SQLITE_OK;
   892         -  }
   893         -  if( pFile->locktype!=NO_LOCK ){
   894         -    /* We cannot change ownership while we are holding a lock! */
   895         -    return SQLITE_MISUSE;
   896         -  }
   897         -  OSTRACE4("Transfer ownership of %d from %d to %d\n",
   898         -            pFile->h, pFile->tid, hSelf);
   899         -  pFile->tid = hSelf;
   900         -  if (pFile->pLock != NULL) {
   901         -    releaseLockInfo(pFile->pLock);
   902         -    rc = findLockInfo(pFile, &pFile->pLock, 0);
   903         -    OSTRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
   904         -           locktypeName(pFile->locktype),
   905         -           locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
   906         -    return rc;
   907         -  } else {
   908         -    return SQLITE_OK;
   909         -  }
   910         -}
   911         -#else  /* if not SQLITE_THREADSAFE */
   912         -  /* On single-threaded builds, ownership transfer is a no-op */
   913         -# define transferOwnership(X) SQLITE_OK
   914         -#endif /* SQLITE_THREADSAFE */
   915         -
   916    822   
   917    823   /*
   918    824   ** Release a unixLockInfo structure previously allocated by findLockInfo().
   919    825   */
   920    826   static void releaseLockInfo(struct unixLockInfo *pLock){
   921    827     if( pLock ){
   922    828       pLock->nRef--;
................................................................................
  1083    989       *ppOpen = pOpen;
  1084    990     }
  1085    991   
  1086    992   exit_findlockinfo:
  1087    993     return rc;
  1088    994   }
  1089    995   
          996  +/*
          997  +** If we are currently in a different thread than the thread that the
          998  +** unixFile argument belongs to, then transfer ownership of the unixFile
          999  +** over to the current thread.
         1000  +**
         1001  +** A unixFile is only owned by a thread on systems that use LinuxThreads.
         1002  +**
         1003  +** Ownership transfer is only allowed if the unixFile is currently unlocked.
         1004  +** If the unixFile is locked and an ownership is wrong, then return
         1005  +** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
         1006  +*/
         1007  +#if SQLITE_THREADSAFE && defined(__linux__)
         1008  +static int transferOwnership(unixFile *pFile){
         1009  +  int rc;
         1010  +  pthread_t hSelf;
         1011  +  if( threadsOverrideEachOthersLocks ){
         1012  +    /* Ownership transfers not needed on this system */
         1013  +    return SQLITE_OK;
         1014  +  }
         1015  +  hSelf = pthread_self();
         1016  +  if( pthread_equal(pFile->tid, hSelf) ){
         1017  +    /* We are still in the same thread */
         1018  +    OSTRACE1("No-transfer, same thread\n");
         1019  +    return SQLITE_OK;
         1020  +  }
         1021  +  if( pFile->locktype!=NO_LOCK ){
         1022  +    /* We cannot change ownership while we are holding a lock! */
         1023  +    return SQLITE_MISUSE;
         1024  +  }
         1025  +  OSTRACE4("Transfer ownership of %d from %d to %d\n",
         1026  +            pFile->h, pFile->tid, hSelf);
         1027  +  pFile->tid = hSelf;
         1028  +  if (pFile->pLock != NULL) {
         1029  +    releaseLockInfo(pFile->pLock);
         1030  +    rc = findLockInfo(pFile, &pFile->pLock, 0);
         1031  +    OSTRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
         1032  +           locktypeName(pFile->locktype),
         1033  +           locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
         1034  +    return rc;
         1035  +  } else {
         1036  +    return SQLITE_OK;
         1037  +  }
         1038  +}
         1039  +#else  /* if not SQLITE_THREADSAFE */
         1040  +  /* On single-threaded builds, ownership transfer is a no-op */
         1041  +# define transferOwnership(X) SQLITE_OK
         1042  +#endif /* SQLITE_THREADSAFE */
         1043  +
  1090   1044   
  1091   1045   /*
  1092   1046   ** This routine checks if there is a RESERVED lock held on the specified
  1093   1047   ** file by this or any other process. If such a lock is held, set *pResOut
  1094   1048   ** to a non-zero value otherwise *pResOut is set to zero.  The return value
  1095   1049   ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
  1096   1050   */
................................................................................
  1642   1596   **         connections from reading or writing the database.
  1643   1597   **
  1644   1598   **    (2)  An application crash or power loss can leave stale lock files
  1645   1599   **         sitting around that need to be cleared manually.
  1646   1600   **
  1647   1601   ** Nevertheless, a dotlock is an appropriate locking mode for use if no
  1648   1602   ** other locking strategy is available.
         1603  +**
         1604  +** Dotfile locking works by creating a file in the same directory as the
         1605  +** database and with the same name but with a ".lock" extension added.
         1606  +** The existance of a lock file implies an EXCLUSIVE lock.  All other lock
         1607  +** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
  1649   1608   */
  1650   1609   
  1651   1610   /*
  1652   1611   ** The file suffix added to the data base filename in order to create the
  1653   1612   ** lock file.
  1654   1613   */
  1655   1614   #define DOTLOCK_SUFFIX ".lock"
  1656   1615   
  1657         -/* Dotlock-style reserved lock checking following the behavior of 
  1658         -** unixCheckReservedLock, see the unixCheckReservedLock function comments */
         1616  +/*
         1617  +** This routine checks if there is a RESERVED lock held on the specified
         1618  +** file by this or any other process. If such a lock is held, set *pResOut
         1619  +** to a non-zero value otherwise *pResOut is set to zero.  The return value
         1620  +** is set to SQLITE_OK unless an I/O error occurs during lock checking.
         1621  +**
         1622  +** In dotfile locking, either a lock exists or it does not.  So in this
         1623  +** variation of CheckReservedLock(), *pResOut is set to true if any lock
         1624  +** is held on the file and false if the file is unlocked.
         1625  +*/
  1659   1626   static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
  1660   1627     int rc = SQLITE_OK;
  1661   1628     int reserved = 0;
  1662   1629     unixFile *pFile = (unixFile*)id;
  1663   1630   
  1664   1631     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  1665   1632     
  1666   1633     assert( pFile );
  1667   1634   
  1668   1635     /* Check if a thread in this process holds such a lock */
  1669   1636     if( pFile->locktype>SHARED_LOCK ){
         1637  +    /* Either this connection or some other connection in the same process
         1638  +    ** holds a lock on the file.  No need to check further. */
  1670   1639       reserved = 1;
  1671         -  }
  1672         -  
  1673         -  /* Otherwise see if some other process holds it. */
  1674         -  if( !reserved ){
  1675         -    char *zLockFile = (char *)pFile->lockingContext;
  1676         -    struct stat statBuf;
  1677         -    
  1678         -    if( lstat(zLockFile, &statBuf)==0 ){
  1679         -      /* file exists, someone else has the lock */
  1680         -      reserved = 1;
  1681         -    }else{
  1682         -      /* file does not exist, we could have it if we want it */
  1683         -      int tErrno = errno;
  1684         -      if( ENOENT != tErrno ){
  1685         -        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
  1686         -        pFile->lastErrno = tErrno;
  1687         -      }
  1688         -    }
         1640  +  }else{
         1641  +    /* The lock is held if and only if the lockfile exists */
         1642  +    const char *zLockFile = (const char*)pFile->lockingContext;
         1643  +    reserved = access(zLockFile, 0)==0;
  1689   1644     }
  1690   1645     OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
  1691         -
  1692   1646     *pResOut = reserved;
  1693   1647     return rc;
  1694   1648   }
  1695   1649   
         1650  +/*
         1651  +** Lock the file with the lock specified by parameter locktype - one
         1652  +** of the following:
         1653  +**
         1654  +**     (1) SHARED_LOCK
         1655  +**     (2) RESERVED_LOCK
         1656  +**     (3) PENDING_LOCK
         1657  +**     (4) EXCLUSIVE_LOCK
         1658  +**
         1659  +** Sometimes when requesting one lock state, additional lock states
         1660  +** are inserted in between.  The locking might fail on one of the later
         1661  +** transitions leaving the lock state different from what it started but
         1662  +** still short of its goal.  The following chart shows the allowed
         1663  +** transitions and the inserted intermediate states:
         1664  +**
         1665  +**    UNLOCKED -> SHARED
         1666  +**    SHARED -> RESERVED
         1667  +**    SHARED -> (PENDING) -> EXCLUSIVE
         1668  +**    RESERVED -> (PENDING) -> EXCLUSIVE
         1669  +**    PENDING -> EXCLUSIVE
         1670  +**
         1671  +** This routine will only increase a lock.  Use the sqlite3OsUnlock()
         1672  +** routine to lower a locking level.
         1673  +**
         1674  +** With dotfile locking, we really only support state (4): EXCLUSIVE.
         1675  +** But we track the other locking levels internally.
         1676  +*/
  1696   1677   static int dotlockLock(sqlite3_file *id, int locktype) {
  1697   1678     unixFile *pFile = (unixFile*)id;
  1698   1679     int fd;
  1699   1680     char *zLockFile = (char *)pFile->lockingContext;
  1700         -  int rc=SQLITE_OK;
         1681  +  int rc = SQLITE_OK;
  1701   1682   
  1702         -  /* if we already have a lock, it is exclusive.  
  1703         -  ** Just adjust level and punt on outta here. */
  1704         -  if (pFile->locktype > NO_LOCK) {
         1683  +
         1684  +  /* If we have any lock, then the lock file already exists.  All we have
         1685  +  ** to do is adjust our internal record of the lock level.
         1686  +  */
         1687  +  if( pFile->locktype > NO_LOCK ){
  1705   1688       pFile->locktype = locktype;
  1706   1689   #if !OS_VXWORKS
  1707   1690       /* Always update the timestamp on the old file */
  1708   1691       utimes(zLockFile, NULL);
  1709   1692   #endif
  1710         -    rc = SQLITE_OK;
  1711         -    goto dotlock_end_lock;
  1712         -  }
  1713         -  
  1714         -  /* check to see if lock file already exists */
  1715         -  struct stat statBuf;
  1716         -  if (lstat(zLockFile,&statBuf) == 0){
  1717         -    rc = SQLITE_BUSY; /* it does, busy */
  1718         -    goto dotlock_end_lock;
         1693  +    return SQLITE_OK;
  1719   1694     }
  1720   1695     
  1721   1696     /* grab an exclusive lock */
  1722   1697     fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
  1723   1698     if( fd<0 ){
  1724   1699       /* failed to open/create the file, someone else may have stolen the lock */
  1725   1700       int tErrno = errno;
................................................................................
  1727   1702         rc = SQLITE_BUSY;
  1728   1703       } else {
  1729   1704         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
  1730   1705         if( IS_LOCK_ERROR(rc) ){
  1731   1706           pFile->lastErrno = tErrno;
  1732   1707         }
  1733   1708       }
  1734         -    goto dotlock_end_lock;
         1709  +    return rc;
  1735   1710     } 
  1736   1711     if( close(fd) ){
  1737   1712       pFile->lastErrno = errno;
  1738   1713       rc = SQLITE_IOERR_CLOSE;
  1739   1714     }
  1740   1715     
  1741   1716     /* got it, set the type and return ok */
  1742   1717     pFile->locktype = locktype;
  1743         -
  1744         - dotlock_end_lock:
  1745   1718     return rc;
  1746   1719   }
  1747   1720   
         1721  +/*
         1722  +** Lower the locking level on file descriptor pFile to locktype.  locktype
         1723  +** must be either NO_LOCK or SHARED_LOCK.
         1724  +**
         1725  +** If the locking level of the file descriptor is already at or below
         1726  +** the requested locking level, this routine is a no-op.
         1727  +**
         1728  +** When the locking level reaches NO_LOCK, delete the lock file.
         1729  +*/
  1748   1730   static int dotlockUnlock(sqlite3_file *id, int locktype) {
  1749   1731     unixFile *pFile = (unixFile*)id;
  1750   1732     char *zLockFile = (char *)pFile->lockingContext;
  1751   1733   
  1752   1734     assert( pFile );
  1753   1735     OSTRACE5("UNLOCK  %d %d was %d pid=%d\n", pFile->h, locktype,
  1754   1736   	   pFile->locktype, getpid());
  1755   1737     assert( locktype<=SHARED_LOCK );
  1756   1738     
  1757   1739     /* no-op if possible */
  1758   1740     if( pFile->locktype==locktype ){
  1759   1741       return SQLITE_OK;
  1760   1742     }
  1761         -  
  1762         -  /* shared can just be set because we always have an exclusive */
  1763         -  if (locktype==SHARED_LOCK) {
  1764         -    pFile->locktype = locktype;
         1743  +
         1744  +  /* To downgrade to shared, simply update our internal notion of the
         1745  +  ** lock state.  No need to mess with the file on disk.
         1746  +  */
         1747  +  if( locktype==SHARED_LOCK ){
         1748  +    pFile->locktype = SHARED_LOCK;
  1765   1749       return SQLITE_OK;
  1766   1750     }
  1767   1751     
  1768         -  /* no, really, unlock. */
  1769         -  if (unlink(zLockFile) ) {
         1752  +  /* To fully unlock the database, delete the lock file */
         1753  +  assert( locktype==NO_LOCK );
         1754  +  if( unlink(zLockFile) ){
  1770   1755       int rc, tErrno = errno;
  1771   1756       if( ENOENT != tErrno ){
  1772   1757         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  1773   1758       }
  1774   1759       if( IS_LOCK_ERROR(rc) ){
  1775   1760         pFile->lastErrno = tErrno;
  1776   1761       }
................................................................................
  1803   1788   **
  1804   1789   ** Use the flock() system call to do file locking.
  1805   1790   **
  1806   1791   ** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
  1807   1792   ** compiling for VXWORKS.
  1808   1793   */
  1809   1794   #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
         1795  +#include <sys/file.h>
  1810   1796   
  1811   1797   /*
  1812   1798   ** The flockLockingContext is not used
  1813   1799   */
  1814   1800   typedef void flockLockingContext;
  1815   1801   
  1816   1802   /* flock-style reserved lock checking following the behavior of 
................................................................................
  1866   1852   #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
  1867   1853     *pResOut = reserved;
  1868   1854     return rc;
  1869   1855   }
  1870   1856   
  1871   1857   static int flockLock(sqlite3_file *id, int locktype) {
  1872   1858     int rc = SQLITE_OK;
  1873         -  int lrc;
  1874   1859     unixFile *pFile = (unixFile*)id;
  1875   1860   
  1876   1861     assert( pFile );
  1877   1862   
  1878   1863     /* if we already have a lock, it is exclusive.  
  1879   1864     ** Just adjust level and punt on outta here. */
  1880   1865     if (pFile->locktype > NO_LOCK) {
................................................................................
  2625   2610   ** Proxy locking is only available on MacOSX 
  2626   2611   */
  2627   2612   #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
  2628   2613   
  2629   2614   
  2630   2615   static int getDbPathForUnixFile(unixFile *pFile, char *dbPath);
  2631   2616   static int getLockPath(const char *dbPath, char *lPath, size_t maxLen);
  2632         -static sqlite3_io_methods *ioMethodForLockingStyle(int style);
  2633   2617   static int createProxyUnixFile(const char *path, unixFile **ppFile);
  2634   2618   static int fillInUnixFile(sqlite3_vfs *pVfs, int h, int dirfd, sqlite3_file *pId, const char *zFilename, int noLock, int isDelete);
  2635   2619   static int takeConch(unixFile *pFile);
  2636   2620   static int releaseConch(unixFile *pFile);
  2637   2621   static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf);
  2638   2622   
  2639         -/*
  2640         -** Tests a byte-range locking query to see if byte range locks are 
  2641         -** supported, if not we fall back to dotlockLockingStyle.
  2642         -** On vxWorks we fall back to semLockingStyle.
  2643         -*/
  2644         -static int testLockingStyle(int fd){
  2645         -  struct flock lockInfo;
  2646         -
  2647         -  /* Test byte-range lock using fcntl(). If the call succeeds, 
  2648         -  ** assume that the file-system supports POSIX style locks. 
  2649         -  */
  2650         -  lockInfo.l_len = 1;
  2651         -  lockInfo.l_start = 0;
  2652         -  lockInfo.l_whence = SEEK_SET;
  2653         -  lockInfo.l_type = F_RDLCK;
  2654         -  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
  2655         -    return LOCKING_STYLE_POSIX;
  2656         -  }
  2657         -  
  2658         -  /* Testing for flock() can give false positives.  So if if the above 
  2659         -  ** test fails, then we fall back to using dot-file style locking (or
  2660         -  ** named-semaphore locking on vxworks).
  2661         -  */
  2662         -  return (OS_VXWORKS ? LOCKING_STYLE_NAMEDSEM : LOCKING_STYLE_DOTFILE);
  2663         -}
  2664         -
  2665   2623   
  2666   2624   #ifdef SQLITE_TEST
  2667   2625   /* simulate multiple hosts by creating unique hostid file paths */
  2668   2626   int sqlite3_hostid_num = 0;
  2669   2627   #endif
  2670   2628   
  2671   2629   /*
................................................................................
  3018   2976         rc = createProxyUnixFile(path, &pCtx->lockProxy);
  3019   2977       }
  3020   2978       if( rc==SQLITE_OK ){
  3021   2979         pCtx->conchHeld = 1;
  3022   2980   
  3023   2981         if( tLockPath ){
  3024   2982           pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath);
  3025         -        if( pCtx->lockProxy->pMethod ==
  3026         -                    ioMethodForLockingStyle(LOCKING_STYLE_AFP) ){
         2983  +        if( pCtx->lockProxy->pMethod == &afpIoMethods ){
  3027   2984             ((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath =
  3028   2985                        pCtx->lockProxyPath;
  3029   2986           }
  3030   2987         }
  3031   2988       } else {
  3032   2989         conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
  3033   2990       }
................................................................................
  3208   3165       /* all memory is allocated, proxys are created and assigned, 
  3209   3166       ** switch the locking context and pMethod then return.
  3210   3167       */
  3211   3168       pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
  3212   3169       pCtx->oldLockingContext = pFile->lockingContext;
  3213   3170       pFile->lockingContext = pCtx;
  3214   3171       pCtx->pOldMethod = pFile->pMethod;
  3215         -    pFile->pMethod = ioMethodForLockingStyle(LOCKING_STYLE_PROXY);
         3172  +    pFile->pMethod = &proxyIoMethods;
  3216   3173     }else{
  3217   3174       if( pCtx->conchFile ){ 
  3218   3175         rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
  3219   3176         if( rc ) return rc;
  3220   3177         sqlite3_free(pCtx->conchFile);
  3221   3178       }
  3222   3179       sqlite3_free(pCtx->conchFilePath); 
................................................................................
  3642   3599   */
  3643   3600   static int unixFileControl(sqlite3_file *id, int op, void *pArg){
  3644   3601     switch( op ){
  3645   3602       case SQLITE_FCNTL_LOCKSTATE: {
  3646   3603         *(int*)pArg = ((unixFile*)id)->locktype;
  3647   3604         return SQLITE_OK;
  3648   3605       }
         3606  +    case SQLITE_LAST_ERRNO: {
         3607  +      *(int*)pArg = ((unixFile*)id)->lastErrno;
         3608  +      return SQLITE_OK;
         3609  +    }
         3610  +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
  3649   3611       case SQLITE_GET_LOCKPROXYFILE: {
  3650         -#if SQLITE_ENABLE_LOCKING_STYLE
  3651   3612         unixFile *pFile = (unixFile*)id;
  3652         -      if( pFile->pMethod == ioMethodForLockingStyle(LOCKING_STYLE_PROXY) ){
         3613  +      if( pFile->pMethod == &proxyIoMethods ){
  3653   3614           proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
  3654   3615           takeConch(pFile);
  3655   3616           if( pCtx->lockProxyPath ){
  3656   3617             *(const char **)pArg = pCtx->lockProxyPath;
  3657   3618           }else{
  3658   3619             *(const char **)pArg = ":auto: (not held)";
  3659   3620           }
  3660   3621         } else {
  3661   3622           *(const char **)pArg = NULL;
  3662   3623         }
  3663         -#else
  3664         -      *(void**)pArg = NULL;
  3665         -#endif
  3666   3624         return SQLITE_OK;
  3667   3625       }
  3668   3626       case SQLITE_SET_LOCKPROXYFILE: {
  3669         -#if SQLITE_ENABLE_LOCKING_STYLE
  3670   3627         unixFile *pFile = (unixFile*)id;
  3671   3628         int rc = SQLITE_OK;
  3672         -      int isProxyStyle = (pFile->pMethod == ioMethodForLockingStyle(LOCKING_STYLE_PROXY));
         3629  +      int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
  3673   3630         if( pArg==NULL || (const char *)pArg==0 ){
  3674   3631           if( isProxyStyle ){
  3675         -          // turn off proxy locking - not supported
         3632  +          /* turn off proxy locking - not supported */
  3676   3633             rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
  3677   3634           }else{
  3678         -          // turn off proxy locking - already off - NOOP
         3635  +          /* turn off proxy locking - already off - NOOP */
  3679   3636             rc = SQLITE_OK;
  3680   3637           }
  3681   3638         }else{
  3682   3639           const char *proxyPath = (const char *)pArg;
  3683   3640           if( isProxyStyle ){
  3684   3641             proxyLockingContext *pCtx = 
  3685   3642               (proxyLockingContext*)pFile->lockingContext;
  3686         -          if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) ){
         3643  +          if( !strcmp(pArg, ":auto:") 
         3644  +           || (pCtx->lockProxyPath &&
         3645  +               !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
         3646  +          ){
  3687   3647               rc = SQLITE_OK;
  3688   3648             }else{
  3689   3649               rc = switchLockProxyPath(pFile, proxyPath);
  3690   3650             }
  3691   3651           }else{
  3692         -          // turn on proxy file locking 
         3652  +          /* turn on proxy file locking */
  3693   3653             rc = transformUnixFileForLockProxy(pFile, proxyPath);
  3694   3654           }
  3695   3655         }
  3696   3656         return rc;
  3697         -#else
  3698         -      return SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
         3657  +    }
  3699   3658   #endif
  3700         -    }
  3701         -    case SQLITE_LAST_ERRNO: {
  3702         -      *(int*)pArg = ((unixFile*)id)->lastErrno;
  3703         -      return SQLITE_OK;
  3704         -    }
  3705         -      
  3706   3659     }
  3707   3660     return SQLITE_ERROR;
  3708   3661   }
  3709   3662   
  3710   3663   /*
  3711   3664   ** Return the sector size in bytes of the underlying block device for
  3712   3665   ** the specified file. This is almost always 512 bytes, but may be
................................................................................
  3733   3686   /*
  3734   3687   ** Here ends the implementation of all sqlite3_file methods.
  3735   3688   **
  3736   3689   ********************** End sqlite3_file Methods *******************************
  3737   3690   ******************************************************************************/
  3738   3691   
  3739   3692   /*
  3740         -** The following constant array describes all of the methods for the
  3741         -** sqlite3_file object for each of the various locking modes.
         3693  +** Each instance of this macro generates two objects:
         3694  +**
         3695  +**   *  A constant sqlite3_io_methods object call METHOD that has locking
         3696  +**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
  3742   3697   **
  3743         -** The order in which the methods are defined is important and must
  3744         -** agree with the numeric values of the method identifier constants.
  3745         -** For example, LOCKING_STYLE_UNIX has a numeric value of zero, so
  3746         -** it must be the 0-th entry in the array.
  3747         -*/
  3748         -#define IOMETHODS(xClose, xLock, xUnlock, xCheckReservedLock) {  \
  3749         -   1,                          /* iVersion */                    \
  3750         -   xClose,                     /* xClose */                      \
  3751         -   unixRead,                   /* xRead */                       \
  3752         -   unixWrite,                  /* xWrite */                      \
  3753         -   unixTruncate,               /* xTruncate */                   \
  3754         -   unixSync,                   /* xSync */                       \
  3755         -   unixFileSize,               /* xFileSize */                   \
  3756         -   xLock,                      /* xLock */                       \
  3757         -   xUnlock,                    /* xUnlock */                     \
  3758         -   xCheckReservedLock,         /* xCheckReservedLock */          \
  3759         -   unixFileControl,            /* xFileControl */                \
  3760         -   unixSectorSize,             /* xSectorSize */                 \
  3761         -   unixDeviceCharacteristics   /* xDeviceCapabilities */         \
  3762         -}
  3763         -static sqlite3_io_methods aIoMethod[] = {
  3764         -  IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock),
  3765         -  IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock),
  3766         -  IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock),
         3698  +**   *  An I/O method finder function called FINDER that returns a pointer
         3699  +**      to the METHOD object in the previous bullet.
         3700  +*/
         3701  +#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK)               \
         3702  +static const sqlite3_io_methods METHOD = {                                   \
         3703  +   1,                          /* iVersion */                                \
         3704  +   CLOSE,                      /* xClose */                                  \
         3705  +   unixRead,                   /* xRead */                                   \
         3706  +   unixWrite,                  /* xWrite */                                  \
         3707  +   unixTruncate,               /* xTruncate */                               \
         3708  +   unixSync,                   /* xSync */                                   \
         3709  +   unixFileSize,               /* xFileSize */                               \
         3710  +   LOCK,                       /* xLock */                                   \
         3711  +   UNLOCK,                     /* xUnlock */                                 \
         3712  +   CKLOCK,                     /* xCheckReservedLock */                      \
         3713  +   unixFileControl,            /* xFileControl */                            \
         3714  +   unixSectorSize,             /* xSectorSize */                             \
         3715  +   unixDeviceCharacteristics   /* xDeviceCapabilities */                     \
         3716  +};                                                                           \
         3717  +static const sqlite3_io_methods *FINDER(const char *z, int h){               \
         3718  +  UNUSED_PARAMETER(z); UNUSED_PARAMETER(h);                                  \
         3719  +  return &METHOD;                                                            \
         3720  +}
         3721  +
         3722  +/*
         3723  +** Here are all of the sqlite3_io_methods objects for each of the
         3724  +** locking strategies.  Functions that return pointers to these methods
         3725  +** are also created.
         3726  +*/
         3727  +IOMETHODS(
         3728  +  posixIoFinder,            /* Finder function name */
         3729  +  posixIoMethods,           /* sqlite3_io_methods object name */
         3730  +  unixClose,                /* xClose method */
         3731  +  unixLock,                 /* xLock method */
         3732  +  unixUnlock,               /* xUnlock method */
         3733  +  unixCheckReservedLock     /* xCheckReservedLock method */
         3734  +);
         3735  +IOMETHODS(
         3736  +  nolockIoFinder,           /* Finder function name */
         3737  +  nolockIoMethods,          /* sqlite3_io_methods object name */
         3738  +  nolockClose,              /* xClose method */
         3739  +  nolockLock,               /* xLock method */
         3740  +  nolockUnlock,             /* xUnlock method */
         3741  +  nolockCheckReservedLock   /* xCheckReservedLock method */
         3742  +);
         3743  +IOMETHODS(
         3744  +  dotlockIoFinder,          /* Finder function name */
         3745  +  dotlockIoMethods,         /* sqlite3_io_methods object name */
         3746  +  dotlockClose,             /* xClose method */
         3747  +  dotlockLock,              /* xLock method */
         3748  +  dotlockUnlock,            /* xUnlock method */
         3749  +  dotlockCheckReservedLock  /* xCheckReservedLock method */
         3750  +);
         3751  +
         3752  +#if SQLITE_ENABLE_LOCKING_STYLE
         3753  +IOMETHODS(
         3754  +  flockIoFinder,            /* Finder function name */
         3755  +  flockIoMethods,           /* sqlite3_io_methods object name */
         3756  +  flockClose,               /* xClose method */
         3757  +  flockLock,                /* xLock method */
         3758  +  flockUnlock,              /* xUnlock method */
         3759  +  flockCheckReservedLock    /* xCheckReservedLock method */
         3760  +);
         3761  +#endif
         3762  +
  3767   3763   #if OS_VXWORKS
  3768         -  IOMETHODS(semClose, semLock, semUnlock, semCheckReservedLock),
  3769         -#elif SQLITE_ENABLE_LOCKING_STYLE
  3770         -  IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock),
         3764  +IOMETHODS(
         3765  +  semIoFinder,              /* Finder function name */
         3766  +  semIoMethods,             /* sqlite3_io_methods object name */
         3767  +  semClose,                 /* xClose method */
         3768  +  semLock,                  /* xLock method */
         3769  +  semUnlock,                /* xUnlock method */
         3770  +  semCheckReservedLock      /* xCheckReservedLock method */
         3771  +);
  3771   3772   #endif
         3773  +
         3774  +#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
         3775  +IOMETHODS(
         3776  +  afpIoFinder,              /* Finder function name */
         3777  +  afpIoMethods,             /* sqlite3_io_methods object name */
         3778  +  afpClose,                 /* xClose method */
         3779  +  afpLock,                  /* xLock method */
         3780  +  afpUnlock,                /* xUnlock method */
         3781  +  afpCheckReservedLock      /* xCheckReservedLock method */
         3782  +);
         3783  +IOMETHODS(
         3784  +  proxyIoFinder,            /* Finder function name */
         3785  +  proxyIoMethods,           /* sqlite3_io_methods object name */
         3786  +  proxyClose,               /* xClose method */
         3787  +  proxyLock,                /* xLock method */
         3788  +  proxyUnlock,              /* xUnlock method */
         3789  +  proxyCheckReservedLock    /* xCheckReservedLock method */
         3790  +);
         3791  +#endif
         3792  +
         3793  +
  3772   3794   #if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
  3773         -  IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock),
  3774         -  IOMETHODS(proxyClose, proxyLock, proxyUnlock, proxyCheckReservedLock),
         3795  +/* 
         3796  +** This procedure attempts to determine the best locking strategy for
         3797  +** the given database file.  It then returns the sqlite3_io_methods
         3798  +** object that implements that strategy.
         3799  +**
         3800  +** This is for MacOSX only.
         3801  +*/
         3802  +static const sqlite3_io_methods *autolockIoFinder(
         3803  +  const char *filePath,    /* name of the database file */
         3804  +  int fd                   /* file descriptor open on the database file */
         3805  +){
         3806  +  static const struct Mapping {
         3807  +    const char *zFilesystem;
         3808  +    const sqlite3_io_methods *pMethods;
         3809  +  } aMap[] = {
         3810  +    { "hfs",    &posixIoMethods },
         3811  +    { "ufs",    &posixIoMethods },
         3812  +    { "afpfs",  &afpIoMethods },
         3813  +#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
         3814  +    { "smbfs",  &afpIoMethods },
         3815  +#else
         3816  +    { "smbfs",  &flockIoMethods },
  3775   3817   #endif
  3776         -  /* The order of the IOMETHODS macros above is important.  It must be the
  3777         -  ** same order as the LOCKING_STYLE numbers
         3818  +    { "webdav", &nolockIoMethods },
         3819  +    { 0, 0 }
         3820  +  };
         3821  +  int i;
         3822  +  struct statfs fsInfo;
         3823  +  struct flock lockInfo;
         3824  +
         3825  +  if( !filePath ){
         3826  +    return &nolockIoMethods;
         3827  +  }
         3828  +  if( statfs(filePath, &fsInfo) != -1 ){
         3829  +    if( fsInfo.f_flags & MNT_RDONLY ){
         3830  +      return &nolockIoMethods;
         3831  +    }
         3832  +    for(i=0; aMap[i].zFilesystem; i++){
         3833  +      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
         3834  +        return aMap[i].pMethods;
         3835  +      }
         3836  +    }
         3837  +  }
         3838  +
         3839  +  /* Default case. Handles, amongst others, "nfs".
         3840  +  ** Test byte-range lock using fcntl(). If the call succeeds, 
         3841  +  ** assume that the file-system supports POSIX style locks. 
  3778   3842     */
  3779         -};
         3843  +  lockInfo.l_len = 1;
         3844  +  lockInfo.l_start = 0;
         3845  +  lockInfo.l_whence = SEEK_SET;
         3846  +  lockInfo.l_type = F_RDLCK;
         3847  +  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
         3848  +    return &posixIoMethods;
         3849  +  }else{
         3850  +    return &dotlockIoMethods;
         3851  +  }
         3852  +}
         3853  +#endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */
         3854  +
         3855  +/*
         3856  +** An abstract type for a pointer to a IO method finder function:
         3857  +*/
         3858  +typedef const sqlite3_io_methods *(*finder_type)(const char*,int);
         3859  +
  3780   3860   
  3781   3861   /****************************************************************************
  3782   3862   **************************** sqlite3_vfs methods ****************************
  3783   3863   **
  3784   3864   ** This division contains the implementation of methods on the
  3785   3865   ** sqlite3_vfs object.
  3786   3866   */
  3787         -
  3788         -/* 
  3789         -** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the 
  3790         -** f_fstypename entry in the statfs structure as returned by stat() for 
  3791         -** the file system hosting the database file and selects  the appropriate
  3792         -** locking style based on its value.  These values and assignments are 
  3793         -** based on Darwin/OSX behavior and have not been thoroughly tested on 
  3794         -** other systems.
  3795         -**
  3796         -** If SQLITE_ENABLE_LOCKING_STYLE is not defined, this function always
  3797         -** returns LOCKING_STYLE_POSIX.
  3798         -*/
  3799         -#if SQLITE_ENABLE_LOCKING_STYLE
  3800         -static int detectLockingStyle(
  3801         -  sqlite3_vfs *pVfs,
  3802         -  const char *filePath, 
  3803         -  int fd
  3804         -){
  3805         -#if OS_VXWORKS
  3806         -  if( !filePath ){
  3807         -    return LOCKING_STYLE_NONE;
  3808         -  }
  3809         -  if( pVfs->pAppData ){
  3810         -    return SQLITE_PTR_TO_INT(pVfs->pAppData);
  3811         -  }
  3812         -  if (access(filePath, 0) != -1){
  3813         -    return testLockingStyle(fd);
  3814         -  }
  3815         -#else
  3816         -  struct Mapping {
  3817         -    const char *zFilesystem;
  3818         -    int eLockingStyle;
  3819         -  } aMap[] = {
  3820         -    { "hfs",    LOCKING_STYLE_POSIX },
  3821         -    { "ufs",    LOCKING_STYLE_POSIX },
  3822         -    { "afpfs",  LOCKING_STYLE_AFP },
  3823         -#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
  3824         -    { "smbfs",  LOCKING_STYLE_AFP },
  3825         -#else
  3826         -    { "smbfs",  LOCKING_STYLE_FLOCK },
  3827         -#endif
  3828         -    { "webdav", LOCKING_STYLE_NONE },
  3829         -    { 0, 0 }
  3830         -  };
  3831         -  int i;
  3832         -  struct statfs fsInfo;
  3833         -
  3834         -  if( !filePath ){
  3835         -    return LOCKING_STYLE_NONE;
  3836         -  }
  3837         -  if( pVfs && pVfs->pAppData ){
  3838         -    return SQLITE_PTR_TO_INT(pVfs->pAppData);
  3839         -  }
  3840         -
  3841         -  if( statfs(filePath, &fsInfo) != -1 ){
  3842         -    if( fsInfo.f_flags & MNT_RDONLY ){
  3843         -      return LOCKING_STYLE_NONE;
  3844         -    }
  3845         -    for(i=0; aMap[i].zFilesystem; i++){
  3846         -      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
  3847         -        return aMap[i].eLockingStyle;
  3848         -      }
  3849         -    }
  3850         -  }
  3851         -
  3852         -  /* Default case. Handles, amongst others, "nfs". */
  3853         -  return testLockingStyle(fd);  
  3854         -#endif /* if OS_VXWORKS */
  3855         -  return LOCKING_STYLE_POSIX;
  3856         -}
  3857         -#else
  3858         -  #define detectLockingStyle(x,y,z) LOCKING_STYLE_POSIX
  3859         -#endif /* if SQLITE_ENABLE_LOCKING_STYLE */
  3860         -
  3861   3867   
  3862   3868   /*
  3863   3869   ** Initialize the contents of the unixFile structure pointed to by pId.
  3864         -**
  3865         -** When locking extensions are enabled, the filepath and locking style 
  3866         -** are needed to determine the unixFile pMethod to use for locking operations.
  3867         -** The locking-style specific lockingContext data structure is created 
  3868         -** and assigned here also.
  3869   3870   */
  3870   3871   static int fillInUnixFile(
  3871   3872     sqlite3_vfs *pVfs,      /* Pointer to vfs object */
  3872   3873     int h,                  /* Open file descriptor of file being opened */
  3873   3874     int dirfd,              /* Directory file descriptor */
  3874   3875     sqlite3_file *pId,      /* Write to the unixFile structure here */
  3875   3876     const char *zFilename,  /* Name of the file being opened */
  3876   3877     int noLock,             /* Omit locking if true */
  3877   3878     int isDelete            /* Delete on close if true */
  3878   3879   ){
  3879         -  int eLockingStyle;
         3880  +  const sqlite3_io_methods *pLockingStyle;
  3880   3881     unixFile *pNew = (unixFile *)pId;
  3881   3882     int rc = SQLITE_OK;
  3882   3883   
  3883   3884     assert( pNew->pLock==NULL );
  3884   3885     assert( pNew->pOpen==NULL );
  3885   3886   
  3886   3887     /* Parameter isDelete is only used on vxworks. Parameter pVfs is only
  3887   3888     ** used if ENABLE_LOCKING_STYLE is defined. Express this explicitly 
  3888   3889     ** here to prevent compiler warnings about unused parameters.
  3889   3890     */
  3890         -  if( !OS_VXWORKS ) UNUSED_PARAMETER(isDelete);
  3891         -  if( !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(pVfs);
  3892         -  if( !OS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(zFilename);
         3891  +#if !OS_VXWORKS
         3892  +  UNUSED_PARAMETER(isDelete);
         3893  +#endif
         3894  +#if !SQLITE_ENABLE_LOCKING_STYLE
         3895  +  UNUSED_PARAMETER(pVfs);
         3896  +#endif
         3897  +#if !OS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE
         3898  +  UNUSED_PARAMETER(zFilename);
         3899  +#endif
  3893   3900   
  3894   3901     OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
  3895   3902     pNew->h = h;
  3896   3903     pNew->dirfd = dirfd;
  3897   3904     SET_THREADID(pNew);
  3898   3905   
  3899   3906   #if OS_VXWORKS
................................................................................
  3901   3908     if( pNew->pId==0 ){
  3902   3909       noLock = 1;
  3903   3910       rc = SQLITE_NOMEM;
  3904   3911     }
  3905   3912   #endif
  3906   3913   
  3907   3914     if( noLock ){
  3908         -    eLockingStyle = LOCKING_STYLE_NONE;
         3915  +    pLockingStyle = &nolockIoMethods;
  3909   3916     }else{
  3910         -    eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
         3917  +    pLockingStyle = (*(finder_type)pVfs->pAppData)(zFilename, h);
  3911   3918   #if SQLITE_ENABLE_LOCKING_STYLE
  3912   3919       /* Cache zFilename in the locking context (AFP and dotlock override) for
  3913   3920       ** proxyLock activation is possible (remote proxy is based on db name)
  3914   3921       ** zFilename remains valid until file is closed, to support */
  3915   3922       pNew->lockingContext = (void*)zFilename;
  3916   3923   #endif
  3917   3924     }
  3918   3925   
  3919         -   
  3920         -  switch( eLockingStyle ){
         3926  +  if( pLockingStyle == &posixIoMethods ){
         3927  +    unixEnterMutex();
         3928  +    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
         3929  +    unixLeaveMutex();
         3930  +  }
  3921   3931   
  3922         -    case LOCKING_STYLE_POSIX: {
         3932  +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
         3933  +  else if( pLockingStyle == &apfIoMethods ){
         3934  +    /* AFP locking uses the file path so it needs to be included in
         3935  +    ** the afpLockingContext.
         3936  +    */
         3937  +    afpLockingContext *pCtx;
         3938  +    pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
         3939  +    if( pCtx==0 ){
         3940  +      rc = SQLITE_NOMEM;
         3941  +    }else{
         3942  +      /* NB: zFilename exists and remains valid until the file is closed
         3943  +      ** according to requirement F11141.  So we do not need to make a
         3944  +      ** copy of the filename. */
         3945  +      pCtx->dbPath = zFilename;
         3946  +      srandomdev();
  3923   3947         unixEnterMutex();
  3924         -      rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
  3925         -      unixLeaveMutex();
  3926         -      break;
         3948  +      rc = findLockInfo(pNew, NULL, &pNew->pOpen);
         3949  +      unixLeaveMutex();        
  3927   3950       }
         3951  +  }
         3952  +#endif
  3928   3953   
  3929   3954   #if SQLITE_ENABLE_LOCKING_STYLE
  3930         -
  3931         -#if !OS_VXWORKS
  3932         -    case LOCKING_STYLE_AFP: {
  3933         -      /* AFP locking uses the file path so it needs to be included in
  3934         -      ** the afpLockingContext.
  3935         -      */
  3936         -      afpLockingContext *pCtx;
  3937         -      pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
  3938         -      if( pCtx==0 ){
  3939         -        rc = SQLITE_NOMEM;
  3940         -      }else{
  3941         -        /* NB: zFilename exists and remains valid until the file is closed
  3942         -        ** according to requirement F11141.  So we do not need to make a
  3943         -        ** copy of the filename. */
  3944         -        pCtx->dbPath = zFilename;
  3945         -        srandomdev();
  3946         -        unixEnterMutex();
  3947         -        rc = findLockInfo(pNew, NULL, &pNew->pOpen);
  3948         -        unixLeaveMutex();        
  3949         -      }
  3950         -      break;
         3955  +  else if( pLockingStyle == &dotlockIoMethods ){
         3956  +    /* Dotfile locking uses the file path so it needs to be included in
         3957  +    ** the dotlockLockingContext 
         3958  +    */
         3959  +    char *zLockFile;
         3960  +    int nFilename;
         3961  +    nFilename = strlen(zFilename) + 6;
         3962  +    zLockFile = (char *)sqlite3_malloc(nFilename);
         3963  +    if( zLockFile==0 ){
         3964  +      rc = SQLITE_NOMEM;
         3965  +    }else{
         3966  +      sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
  3951   3967       }
         3968  +    pNew->lockingContext = zLockFile;
         3969  +  }
  3952   3970   #endif
  3953   3971   
  3954         -    case LOCKING_STYLE_DOTFILE: {
  3955         -      /* Dotfile locking uses the file path so it needs to be included in
  3956         -      ** the dotlockLockingContext 
  3957         -      */
  3958         -      char *zLockFile;
  3959         -      int nFilename;
  3960         -      nFilename = strlen(zFilename) + 6;
  3961         -      zLockFile = (char *)sqlite3_malloc(nFilename);
  3962         -      if( zLockFile==0 ){
  3963         -        rc = SQLITE_NOMEM;
  3964         -      }else{
  3965         -        sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
  3966         -      }
  3967         -      pNew->lockingContext = zLockFile;
  3968         -      break;
  3969         -    }
  3970         -
  3971   3972   #if OS_VXWORKS
  3972         -    case LOCKING_STYLE_NAMEDSEM: {
  3973         -      /* Named semaphore locking uses the file path so it needs to be
  3974         -      ** included in the semLockingContext
  3975         -      */
  3976         -      unixEnterMutex();
  3977         -      rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
  3978         -      if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
  3979         -        char *zSemName = pNew->pOpen->aSemName;
  3980         -        int n;
  3981         -        sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
  3982         -                         pNew->pId->zCanonicalName);
  3983         -        for( n=0; zSemName[n]; n++ )
  3984         -          if( zSemName[n]=='/' ) zSemName[n] = '_';
  3985         -        pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
  3986         -        if( pNew->pOpen->pSem == SEM_FAILED ){
  3987         -          rc = SQLITE_NOMEM;
  3988         -          pNew->pOpen->aSemName[0] = '\0';
  3989         -        }
         3973  +  else if( pLockingStyle == &semIoMethods ){
         3974  +    /* Named semaphore locking uses the file path so it needs to be
         3975  +    ** included in the semLockingContext
         3976  +    */
         3977  +    unixEnterMutex();
         3978  +    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
         3979  +    if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
         3980  +      char *zSemName = pNew->pOpen->aSemName;
         3981  +      int n;
         3982  +      sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
         3983  +                       pNew->pId->zCanonicalName);
         3984  +      for( n=0; zSemName[n]; n++ )
         3985  +        if( zSemName[n]=='/' ) zSemName[n] = '_';
         3986  +      pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
         3987  +      if( pNew->pOpen->pSem == SEM_FAILED ){
         3988  +        rc = SQLITE_NOMEM;
         3989  +        pNew->pOpen->aSemName[0] = '\0';
  3990   3990         }
  3991         -      unixLeaveMutex();
  3992         -      break;
  3993   3991       }
         3992  +    unixLeaveMutex();
         3993  +  }
  3994   3994   #endif
  3995         -
  3996         -    case LOCKING_STYLE_FLOCK: 
  3997         -    case LOCKING_STYLE_NONE: 
  3998         -      break;
  3999         -#endif
  4000         -  }
  4001   3995     
  4002   3996     pNew->lastErrno = 0;
  4003   3997   #if OS_VXWORKS
  4004   3998     if( rc!=SQLITE_OK ){
  4005   3999       unlink(zFilename);
  4006   4000       isDelete = 0;
  4007   4001     }
  4008   4002     pNew->isDelete = isDelete;
  4009   4003   #endif
  4010   4004     if( rc!=SQLITE_OK ){
  4011   4005       if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
  4012   4006       close(h);
  4013   4007     }else{
  4014         -    pNew->pMethod = &aIoMethod[eLockingStyle-1];
         4008  +    pNew->pMethod = pLockingStyle;
  4015   4009       OpenCounter(+1);
  4016   4010     }
  4017   4011     return rc;
  4018   4012   }
  4019   4013   
  4020   4014   #if SQLITE_ENABLE_LOCKING_STYLE
  4021         -static sqlite3_io_methods *ioMethodForLockingStyle(int style){
  4022         -  return &aIoMethod[style];
  4023         -}
  4024         -
  4025   4015   static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){
  4026         -  if( pFile->pMethod==ioMethodForLockingStyle(LOCKING_STYLE_AFP) ){
         4016  +#if defined(__DARWIN__)
         4017  +  if( pFile->pMethod == &afpIoMethods ){
  4027   4018       /* afp style keeps a reference to the db path in the filePath field 
  4028   4019       ** of the struct */
  4029         -    strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, 
  4030         -            MAXPATHLEN);
  4031         -    return SQLITE_OK;
  4032         -  }
  4033         -  if( pFile->pMethod==ioMethodForLockingStyle(LOCKING_STYLE_DOTFILE) ){
         4020  +    assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
         4021  +    strcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath)
         4022  +  }else
         4023  +#endif
         4024  +  if( pFile->pMethod == &dotlockIoMethods ){
  4034   4025       /* dot lock style uses the locking context to store the dot lock
  4035   4026       ** file path */
  4036   4027       int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
  4037         -    strlcpy(dbPath, (char *)pFile->lockingContext, len + 1);
  4038         -    return SQLITE_OK;
         4028  +    memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
         4029  +  }else{
         4030  +    /* all other styles use the locking context to store the db file path */
         4031  +    assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
         4032  +    strcpy(dbPath, (char *)pFile->lockingContext);
  4039   4033     }
  4040         -  /* all other styles use the locking context to store the db file path */
  4041         -  strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN);
  4042   4034     return SQLITE_OK;
  4043   4035   }
  4044   4036   #endif
  4045   4037   
  4046   4038   /*
  4047   4039   ** Open a file descriptor to the directory containing file zFilename.
  4048   4040   ** If successful, *pFd is set to the opened file descriptor and
................................................................................
  4279   4271   
  4280   4272   #if SQLITE_PREFER_PROXY_LOCKING
  4281   4273     if( zPath!=NULL && !noLock ){
  4282   4274       char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
  4283   4275       int useProxy = 0;
  4284   4276   
  4285   4277       /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 
  4286         -     ** 0 means never use proxy, NULL means use proxy for non-local files only
  4287         -     */
         4278  +    ** 0 means never use proxy, NULL means use proxy for non-local files only
         4279  +    */
  4288   4280       if( envforce!=NULL ){
  4289   4281         useProxy = atoi(envforce)>0;
  4290   4282       }else{
  4291   4283         struct statfs fsInfo;
  4292   4284   
  4293   4285         if( statfs(zPath, &fsInfo) == -1 ){
  4294   4286   				((unixFile*)pFile)->lastErrno = errno;
................................................................................
  4591   4583   */
  4592   4584   int sqlite3_os_init(void){ 
  4593   4585     /* Macro to define the static contents of an sqlite3_vfs structure for
  4594   4586     ** the unix backend. The two parameters are the values to use for
  4595   4587     ** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively.
  4596   4588     ** 
  4597   4589     */
  4598         -  #define UNIXVFS(zVfsName, pVfsAppData) {                  \
         4590  +  #define UNIXVFS(VFSNAME, FINDER) {                        \
  4599   4591       1,                    /* iVersion */                    \
  4600   4592       sizeof(unixFile),     /* szOsFile */                    \
  4601   4593       MAX_PATHNAME,         /* mxPathname */                  \
  4602   4594       0,                    /* pNext */                       \
  4603         -    zVfsName,             /* zName */                       \
  4604         -    (void *)pVfsAppData,  /* pAppData */                    \
         4595  +    VFSNAME,              /* zName */                       \
         4596  +    (void*)FINDER,        /* pAppData */                    \
  4605   4597       unixOpen,             /* xOpen */                       \
  4606   4598       unixDelete,           /* xDelete */                     \
  4607   4599       unixAccess,           /* xAccess */                     \
  4608   4600       unixFullPathname,     /* xFullPathname */               \
  4609   4601       unixDlOpen,           /* xDlOpen */                     \
  4610   4602       unixDlError,          /* xDlError */                    \
  4611   4603       unixDlSym,            /* xDlSym */                      \
................................................................................
  4612   4604       unixDlClose,          /* xDlClose */                    \
  4613   4605       unixRandomness,       /* xRandomness */                 \
  4614   4606       unixSleep,            /* xSleep */                      \
  4615   4607       unixCurrentTime,      /* xCurrentTime */                \
  4616   4608       unixGetLastError      /* xGetLastError */               \
  4617   4609     }
  4618   4610   
  4619         -  int i;
         4611  +  unsigned int i;
  4620   4612     static sqlite3_vfs aVfs[] = {
  4621         -    UNIXVFS("unix",         LOCKING_STYLE_AUTOMATIC), 
  4622         -    UNIXVFS("unix-posix",   LOCKING_STYLE_POSIX), 
  4623         -    UNIXVFS("unix-none",    LOCKING_STYLE_NONE),
  4624         -    UNIXVFS("unix-dotfile", LOCKING_STYLE_DOTFILE),
         4613  +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
         4614  +    UNIXVFS("unix",          autolockIoFinder ),
         4615  +#else
         4616  +    UNIXVFS("unix",          posixIoFinder ),
         4617  +#endif
         4618  +    UNIXVFS("unix-none",     nolockIoFinder ),
         4619  +    UNIXVFS("unix-dotfile",  dotlockIoFinder ),
  4625   4620   #if OS_VXWORKS
  4626         -    UNIXVFS("unix-namedsem",LOCKING_STYLE_NAMEDSEM),
         4621  +    UNIXVFS("unix-namedsem", semIoFinder ),
  4627   4622   #endif
  4628   4623   #if SQLITE_ENABLE_LOCKING_STYLE
  4629         -    UNIXVFS("unix-flock",   LOCKING_STYLE_FLOCK), 
         4624  +    UNIXVFS("unix-posix",    posixIoFinder ),
         4625  +    UNIXVFS("unix-flock",    flockIoFinder ),
  4630   4626   #endif
  4631   4627   #if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
  4632         -    UNIXVFS("unix-afp",     LOCKING_STYLE_AFP), 
  4633         -    UNIXVFS("unix-proxy",   LOCKING_STYLE_PROXY)
         4628  +    UNIXVFS("unix-afp",      afpIoFinder ),
         4629  +    UNIXVFS("unix-proxy",    proxyIoFinder ),
  4634   4630   #endif
  4635   4631     };
  4636   4632     for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
  4637   4633       sqlite3_vfs_register(&aVfs[i], i==0);
  4638   4634     }
  4639   4635     return SQLITE_OK; 
  4640   4636   }

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.332 2008/11/28 15:37:20 drh Exp $
           16  +** $Id: test1.c,v 1.333 2008/11/29 00:56:53 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   
    23     23   /*
................................................................................
  4523   4523     if( objc!=2 ){
  4524   4524       Tcl_AppendResult(interp, "wrong # args: should be \"",
  4525   4525                        Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
  4526   4526       return TCL_ERROR;
  4527   4527     }
  4528   4528     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  4529   4529     
  4530         -#ifdef SQLITE_ENABLE_LOCKING_STYLE
  4531         -	{
         4530  +#if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__)
         4531  +  {
  4532   4532       char *proxyPath = "test.proxy";
  4533   4533       char *testPath;
  4534         -		rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
  4535         -    if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
         4534  +    rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
         4535  +    if( rc ){
         4536  +      Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR;
         4537  +    }
  4536   4538       rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
  4537   4539       if( strncmp(proxyPath,testPath,11) ) {
  4538         -      Tcl_AppendResult(interp, "Lock proxy file did not match the previously assigned value", 0);
         4540  +      Tcl_AppendResult(interp, "Lock proxy file did not match the "
         4541  +                               "previously assigned value", 0);
         4542  +      return TCL_ERROR;
         4543  +    }
         4544  +    if( rc ){
         4545  +      Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  4539   4546         return TCL_ERROR;
  4540   4547       }
  4541         -    if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
  4542         -		rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
  4543         -    if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
         4548  +    rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
         4549  +    if( rc ){
         4550  +      Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         4551  +      return TCL_ERROR;
         4552  +    }
  4544   4553     }
  4545   4554   #endif
  4546   4555     return TCL_OK;  
  4547   4556   }
  4548   4557   
  4549   4558   
  4550   4559   /*

Changes to src/test_config.c.

    12     12   ** 
    13     13   ** This file contains code used for testing the SQLite system.
    14     14   ** None of the code in this file goes into a deliverable build.
    15     15   ** 
    16     16   ** The focus of this file is providing the TCL testing layer
    17     17   ** access to compile-time constants.
    18     18   **
    19         -** $Id: test_config.c,v 1.43 2008/11/21 00:10:35 aswift Exp $
           19  +** $Id: test_config.c,v 1.44 2008/11/29 00:56:54 drh Exp $
    20     20   */
    21     21   
    22     22   #include "sqliteLimit.h"
    23     23   
    24     24   #include "sqliteInt.h"
    25     25   #include "tcl.h"
    26     26   #include <stdlib.h>
................................................................................
   388    388   
   389    389   #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
   390    390     Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY);
   391    391   #else
   392    392     Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
   393    393   #endif
   394    394   
   395         -#ifdef SQLITE_ENABLE_LOCKING_STYLE
   396         -    Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "1", TCL_GLOBAL_ONLY);
          395  +#if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__)
          396  +  Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","1",TCL_GLOBAL_ONLY);
   397    397   #else
   398         -    Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "0", TCL_GLOBAL_ONLY);
          398  +  Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","0",TCL_GLOBAL_ONLY);
   399    399   #endif
   400    400       
   401    401       
   402    402   #ifdef SQLITE_OMIT_SHARED_CACHE
   403    403     Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY);
   404    404   #else
   405    405     Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "1", TCL_GLOBAL_ONLY);