/ Check-in [aa6acfa8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem in os_unix.c where a malloc failure could lead to a leaked file descriptor.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: aa6acfa8caa2ef59b4c16dfe42c4b5644da96905
User & Date: dan 2009-08-22 11:39:47
References
2009-08-25
12:11
Merge together the os_unix.c fix of [aa6acfa8ca] and the trigger fix of [dee1b8eb40]. check-in: 1e2c6e13 user: drh tags: trunk
Context
2009-08-22
19:17
Remove an obsolete documentation file left over from SQLite version 1.0. check-in: f7eb1efc user: drh tags: trunk
11:39
Fix a problem in os_unix.c where a malloc failure could lead to a leaked file descriptor. check-in: aa6acfa8 user: dan tags: trunk
2009-08-21
17:18
When a database file is opened, try to find an unused file descriptor to reuse. This change affects unix (and other systems that use os_unix.c) only. Fix for cvstrac ticket #4018. check-in: 9b4d9ab6 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

   163    163   /*
   164    164   ** Only set the lastErrno if the error code is a real error and not 
   165    165   ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
   166    166   */
   167    167   #define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
   168    168   
   169    169   
          170  +/*
          171  +** Sometimes, after a file handle is closed by SQLite, the file descriptor
          172  +** cannot be closed immediately. In these cases, instances of the following
          173  +** structure are used to store the file descriptor while waiting for an
          174  +** opportunity to either close or reuse it.
          175  +*/
          176  +typedef struct UnixUnusedFd UnixUnusedFd;
          177  +struct UnixUnusedFd {
          178  +  int fd;                   /* File descriptor to close */
          179  +  int flags;                /* Flags this file descriptor was opened with */
          180  +  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
          181  +};
          182  +
   170    183   /*
   171    184   ** The unixFile structure is subclass of sqlite3_file specific to the unix
   172    185   ** VFS implementations.
   173    186   */
   174    187   typedef struct unixFile unixFile;
   175    188   struct unixFile {
   176    189     sqlite3_io_methods const *pMethod;  /* Always the first entry */
................................................................................
   177    190     struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
   178    191     struct unixLockInfo *pLock;      /* Info about locks on this inode */
   179    192     int h;                           /* The file descriptor */
   180    193     int dirfd;                       /* File descriptor for the directory */
   181    194     unsigned char locktype;          /* The type of lock held on this fd */
   182    195     int lastErrno;                   /* The unix errno from the last I/O error */
   183    196     void *lockingContext;            /* Locking style specific state */
   184         -  int flags;                       /* Flags value returned by xOpen() */
          197  +  UnixUnusedFd *pUnused;           /* Pre-allocated UnixUnusedFd */
   185    198   #if SQLITE_ENABLE_LOCKING_STYLE
   186    199     int openFlags;                   /* The flags specified at open() */
   187    200   #endif
   188    201   #if SQLITE_THREADSAFE && defined(__linux__)
   189    202     pthread_t tid;                   /* The thread that "owns" this unixFile */
   190    203   #endif
   191    204   #if OS_VXWORKS
................................................................................
   744    757   ** The close() system call would only occur when the last database
   745    758   ** using the file closes.
   746    759   */
   747    760   struct unixOpenCnt {
   748    761     struct unixFileId fileId;   /* The lookup key */
   749    762     int nRef;                   /* Number of pointers to this structure */
   750    763     int nLock;                  /* Number of outstanding locks */
   751         -  int nPending;               /* Number of pending close() operations */
   752         -  struct PendingClose {
   753         -    int fd;                   /* File descriptor to close */
   754         -    int flags;                /* Flags this file descriptor was opened with */
   755         -  } *aPending;                /* Malloced space holding fds awaiting close() */
          764  +  UnixUnusedFd *pUnused;      /* Unused file descriptors to close */
   756    765   #if OS_VXWORKS
   757    766     sem_t *pSem;                     /* Named POSIX semaphore */
   758    767     char aSemName[MAX_PATHNAME+1];   /* Name of that semaphore */
   759    768   #endif
   760    769     struct unixOpenCnt *pNext, *pPrev;   /* List of all unixOpenCnt objects */
   761    770   };
   762    771   
................................................................................
   906    915           assert( openList==pOpen );
   907    916           openList = pOpen->pNext;
   908    917         }
   909    918         if( pOpen->pNext ){
   910    919           assert( pOpen->pNext->pPrev==pOpen );
   911    920           pOpen->pNext->pPrev = pOpen->pPrev;
   912    921         }
   913         -      sqlite3_free(pOpen->aPending);
          922  +      assert( !pOpen->pUnused );
   914    923         sqlite3_free(pOpen);
   915    924       }
   916    925     }
   917    926   }
   918    927   
   919    928   /*
   920    929   ** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
................................................................................
  1024   1033       if( pOpen==0 ){
  1025   1034         pOpen = sqlite3_malloc( sizeof(*pOpen) );
  1026   1035         if( pOpen==0 ){
  1027   1036           releaseLockInfo(pLock);
  1028   1037           rc = SQLITE_NOMEM;
  1029   1038           goto exit_findlockinfo;
  1030   1039         }
         1040  +      memset(pOpen, 0, sizeof(*pOpen));
  1031   1041         pOpen->fileId = fileId;
  1032   1042         pOpen->nRef = 1;
  1033         -      pOpen->nLock = 0;
  1034         -      pOpen->nPending = 0;
  1035         -      pOpen->aPending = 0;
  1036   1043         pOpen->pNext = openList;
  1037         -      pOpen->pPrev = 0;
  1038   1044         if( openList ) openList->pPrev = pOpen;
  1039   1045         openList = pOpen;
  1040         -#if OS_VXWORKS
  1041         -      pOpen->pSem = NULL;
  1042         -      pOpen->aSemName[0] = '\0';
  1043         -#endif
  1044   1046       }else{
  1045   1047         pOpen->nRef++;
  1046   1048       }
  1047   1049       *ppOpen = pOpen;
  1048   1050     }
  1049   1051   
  1050   1052   exit_findlockinfo:
................................................................................
  1401   1403     unixLeaveMutex();
  1402   1404     OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
  1403   1405         rc==SQLITE_OK ? "ok" : "failed");
  1404   1406     return rc;
  1405   1407   }
  1406   1408   
  1407   1409   /*
  1408         -** Close all file descriptors accumuated in the p->aPending[] array. If
  1409         -** all such file descriptors are closed without error, the aPending[] 
  1410         -** array is deleted and SQLITE_OK returned.
         1410  +** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
         1411  +** If all such file descriptors are closed without error, the list is
         1412  +** cleared and SQLITE_OK returned.
  1411   1413   **
  1412   1414   ** Otherwise, if an error occurs, then successfully closed file descriptor
  1413         -** entries in the aPending[] array are set to -1, the aPending[] array
         1415  +** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
  1414   1416   ** not deleted and SQLITE_IOERR_CLOSE returned.
  1415   1417   */ 
  1416   1418   static int closePendingFds(unixFile *pFile){
         1419  +  int rc = SQLITE_OK;
  1417   1420     struct unixOpenCnt *pOpen = pFile->pOpen;
  1418         -  struct PendingClose *aPending = pOpen->aPending;
  1419         -  int i;
  1420         -  int rc = SQLITE_OK;
  1421         -  assert( unixMutexHeld() );
  1422         -  for(i=0; i<pOpen->nPending; i++){
  1423         -    if( aPending[i].fd>=0 ){
  1424         -      if( close(aPending[i].fd) ){
  1425         -        pFile->lastErrno = errno;
  1426         -        rc = SQLITE_IOERR_CLOSE;
  1427         -      }else{
  1428         -        aPending[i].fd = -1;
  1429         -      }
         1421  +  UnixUnusedFd *pError = 0;
         1422  +  UnixUnusedFd *p;
         1423  +  UnixUnusedFd *pNext;
         1424  +  for(p=pOpen->pUnused; p; p=pNext){
         1425  +    pNext = p->pNext;
         1426  +    if( close(p->fd) ){
         1427  +      pFile->lastErrno = errno;
         1428  +      rc = SQLITE_IOERR_CLOSE;
         1429  +      p->pNext = pError;
         1430  +      pError = p;
         1431  +      assert(0);
         1432  +    }else{
         1433  +      sqlite3_free(p);
  1430   1434       }
  1431   1435     }
  1432         -  if( rc==SQLITE_OK ){
  1433         -    sqlite3_free(aPending);
  1434         -    pOpen->nPending = 0;
  1435         -    pOpen->aPending = 0;
  1436         -  }
         1436  +  pOpen->pUnused = pError;
  1437   1437     return rc;
  1438   1438   }
  1439   1439   
  1440   1440   /*
  1441   1441   ** Add the file descriptor used by file handle pFile to the corresponding
  1442         -** aPending[] array to be closed after some other connection releases
  1443         -** a lock.
         1442  +** pUnused list.
  1444   1443   */
  1445   1444   static void setPendingFd(unixFile *pFile){
  1446         -  struct PendingClose *aNew;
  1447   1445     struct unixOpenCnt *pOpen = pFile->pOpen;
  1448         -  int nByte = (pOpen->nPending+1)*sizeof(pOpen->aPending[0]);
  1449         -  aNew = sqlite3_realloc(pOpen->aPending, nByte);
  1450         -  if( aNew==0 ){
  1451         -    /* If a malloc fails, just leak the file descriptor */
  1452         -  }else{
  1453         -    pOpen->aPending = aNew;
  1454         -    pOpen->aPending[pOpen->nPending].fd = pFile->h;
  1455         -    pOpen->aPending[pOpen->nPending].flags = pFile->flags;
  1456         -    pOpen->nPending++;
  1457         -    pFile->h = -1;
  1458         -  }
         1446  +  UnixUnusedFd *p = pFile->pUnused;
         1447  +  p->pNext = pOpen->pUnused;
         1448  +  pOpen->pUnused = p;
         1449  +  pFile->h = -1;
         1450  +  pFile->pUnused = 0;
  1459   1451   }
  1460   1452   
  1461   1453   /*
  1462   1454   ** Lower the locking level on file descriptor pFile to locktype.  locktype
  1463   1455   ** must be either NO_LOCK or SHARED_LOCK.
  1464   1456   **
  1465   1457   ** If the locking level of the file descriptor is already at or below
................................................................................
  1569   1561       /* Decrement the count of locks against this same file.  When the
  1570   1562       ** count reaches zero, close any other file descriptors whose close
  1571   1563       ** was deferred because of outstanding locks.
  1572   1564       */
  1573   1565       pOpen = pFile->pOpen;
  1574   1566       pOpen->nLock--;
  1575   1567       assert( pOpen->nLock>=0 );
  1576         -    if( pOpen->nLock==0 && pOpen->nPending>0 ){
         1568  +    if( pOpen->nLock==0 ){
  1577   1569         int rc2 = closePendingFds(pFile);
  1578   1570         if( rc==SQLITE_OK ){
  1579   1571           rc = rc2;
  1580   1572         }
  1581   1573       }
  1582   1574     }
  1583   1575   	
................................................................................
  1623   1615         }
  1624   1616         vxworksReleaseFileId(pFile->pId);
  1625   1617         pFile->pId = 0;
  1626   1618       }
  1627   1619   #endif
  1628   1620       OSTRACE2("CLOSE   %-3d\n", pFile->h);
  1629   1621       OpenCounter(-1);
         1622  +    sqlite3_free(pFile->pUnused);
  1630   1623       memset(pFile, 0, sizeof(unixFile));
  1631   1624     }
  1632   1625     return SQLITE_OK;
  1633   1626   }
  1634   1627   
  1635   1628   /*
  1636   1629   ** Close a file.
................................................................................
  1640   1633     if( id ){
  1641   1634       unixFile *pFile = (unixFile *)id;
  1642   1635       unixUnlock(id, NO_LOCK);
  1643   1636       unixEnterMutex();
  1644   1637       if( pFile->pOpen && pFile->pOpen->nLock ){
  1645   1638         /* If there are outstanding locks, do not actually close the file just
  1646   1639         ** yet because that would clear those locks.  Instead, add the file
  1647         -      ** descriptor to pOpen->aPending.  It will be automatically closed when
  1648         -      ** the last lock is cleared.
         1640  +      ** descriptor to pOpen->pUnused list.  It will be automatically closed 
         1641  +      ** when the last lock is cleared.
  1649   1642         */
  1650   1643         setPendingFd(pFile);
  1651   1644       }
  1652   1645       releaseLockInfo(pFile->pLock);
  1653   1646       releaseOpenCnt(pFile->pOpen);
  1654   1647       rc = closeUnixFile(id);
  1655   1648       unixLeaveMutex();
................................................................................
  2730   2723   ){
  2731   2724     unixFile *pFile = (unixFile *)id;
  2732   2725     int got;
  2733   2726     assert( id );
  2734   2727   
  2735   2728     /* If this is a database file (not a journal, master-journal or temp
  2736   2729     ** file), the bytes in the locking range should never be read or written. */
  2737         -  assert( (pFile->flags&SQLITE_OPEN_MAIN_DB)==0
         2730  +  assert( pFile->pUnused==0
  2738   2731          || offset>=PENDING_BYTE+512
  2739   2732          || offset+amt<=PENDING_BYTE 
  2740   2733     );
  2741   2734   
  2742   2735     got = seekAndRead(pFile, offset, pBuf, amt);
  2743   2736     if( got==amt ){
  2744   2737       return SQLITE_OK;
................................................................................
  2803   2796     unixFile *pFile = (unixFile*)id;
  2804   2797     int wrote = 0;
  2805   2798     assert( id );
  2806   2799     assert( amt>0 );
  2807   2800   
  2808   2801     /* If this is a database file (not a journal, master-journal or temp
  2809   2802     ** file), the bytes in the locking range should never be read or written. */
  2810         -  assert( (pFile->flags&SQLITE_OPEN_MAIN_DB)==0
         2803  +  assert( pFile->pUnused==0
  2811   2804          || offset>=PENDING_BYTE+512
  2812   2805          || offset+amt<=PENDING_BYTE 
  2813   2806     );
  2814   2807   
  2815   2808   #ifndef NDEBUG
  2816   2809     /* If we are doing a normal write to a database file (as opposed to
  2817   2810     ** doing a hot-journal rollback or a write to some file other than a
................................................................................
  3170   3163   ** looks at the filesystem type and tries to guess the best locking
  3171   3164   ** strategy from that.
  3172   3165   **
  3173   3166   ** For finder-funtion F, two objects are created:
  3174   3167   **
  3175   3168   **    (1) The real finder-function named "FImpt()".
  3176   3169   **
  3177         -**    (2) A constant pointer to this functio named just "F".
         3170  +**    (2) A constant pointer to this function named just "F".
  3178   3171   **
  3179   3172   **
  3180   3173   ** A pointer to the F pointer is used as the pAppData value for VFS
  3181   3174   ** objects.  We have to do this instead of letting pAppData point
  3182   3175   ** directly at the finder-function since C90 rules prevent a void*
  3183   3176   ** from be cast into a function pointer.
  3184   3177   **
................................................................................
  3434   3427     const sqlite3_io_methods *pLockingStyle;
  3435   3428     unixFile *pNew = (unixFile *)pId;
  3436   3429     int rc = SQLITE_OK;
  3437   3430   
  3438   3431     assert( pNew->pLock==NULL );
  3439   3432     assert( pNew->pOpen==NULL );
  3440   3433   
  3441         -  /* Parameter isDelete is only used on vxworks.
  3442         -  ** Express this explicitly here to prevent compiler warnings
  3443         -  ** about unused parameters.
         3434  +  /* Parameter isDelete is only used on vxworks. Express this explicitly 
         3435  +  ** here to prevent compiler warnings about unused parameters.
  3444   3436     */
  3445         -#if !OS_VXWORKS
  3446   3437     UNUSED_PARAMETER(isDelete);
  3447         -#endif
  3448   3438   
  3449   3439     OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
  3450   3440     pNew->h = h;
  3451   3441     pNew->dirfd = dirfd;
  3452   3442     SET_THREADID(pNew);
  3453   3443   
  3454   3444   #if OS_VXWORKS
................................................................................
  3470   3460       pNew->lockingContext = (void*)zFilename;
  3471   3461   #endif
  3472   3462     }
  3473   3463   
  3474   3464     if( pLockingStyle == &posixIoMethods ){
  3475   3465       unixEnterMutex();
  3476   3466       rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
         3467  +    if( rc!=SQLITE_OK ){
         3468  +      /* If an error occured in findLockInfo(), close the file descriptor
         3469  +      ** immediately, before releasing the mutex. findLockInfo() may fail
         3470  +      ** in two scenarios:
         3471  +      **
         3472  +      **   (a) A call to fstat() failed.
         3473  +      **   (b) A malloc failed.
         3474  +      **
         3475  +      ** Scenario (b) may only occur if the process is holding no other
         3476  +      ** file descriptors open on the same file. If there were other file
         3477  +      ** descriptors on this file, then no malloc would be required by
         3478  +      ** findLockInfo(). If this is the case, it is quite safe to close
         3479  +      ** handle h - as it is guaranteed that no posix locks will be released
         3480  +      ** by doing so.
         3481  +      **
         3482  +      ** If scenario (a) caused the error then things are not so safe. The
         3483  +      ** implicit assumption here is that if fstat() fails, things are in
         3484  +      ** such bad shape that dropping a lock or two doesn't matter much.
         3485  +      */
         3486  +      close(h);
         3487  +      h = -1;
         3488  +    }
  3477   3489       unixLeaveMutex();
  3478   3490     }
  3479   3491   
  3480   3492   #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
  3481   3493     else if( pLockingStyle == &afpIoMethods ){
  3482   3494       /* AFP locking uses the file path so it needs to be included in
  3483   3495       ** the afpLockingContext.
................................................................................
  3545   3557       unlink(zFilename);
  3546   3558       isDelete = 0;
  3547   3559     }
  3548   3560     pNew->isDelete = isDelete;
  3549   3561   #endif
  3550   3562     if( rc!=SQLITE_OK ){
  3551   3563       if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
  3552         -    close(h);
         3564  +    if( h>=0 ) close(h);
  3553   3565     }else{
  3554   3566       pNew->pMethod = pLockingStyle;
  3555   3567       OpenCounter(+1);
  3556   3568     }
  3557   3569     return rc;
  3558   3570   }
  3559   3571   
................................................................................
  3670   3682   ** Refer to comments in the unixClose() function and the lengthy comment
  3671   3683   ** describing "Posix Advisory Locking" at the start of this file for 
  3672   3684   ** further details. Also, ticket #4018.
  3673   3685   **
  3674   3686   ** If a suitable file descriptor is found, then it is returned. If no
  3675   3687   ** such file descriptor is located, -1 is returned.
  3676   3688   */
  3677         -static int findReusableFd(const char *zPath, int flags){
  3678         -  int fd = -1;                         /* Return value */
         3689  +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
         3690  +  UnixUnusedFd *pUnused = 0;
         3691  +
         3692  +  /* Do not search for an unused file descriptor on vxworks. Not because
         3693  +  ** vxworks would not benefit from the change (it might, we're not sure),
         3694  +  ** but because no way to test it is currently available. It is better 
         3695  +  ** not to risk breaking vxworks support for the sake of such an obscure 
         3696  +  ** feature.  */
         3697  +#if !OS_VXWORKS
  3679   3698     struct stat sStat;                   /* Results of stat() call */
  3680   3699   
  3681   3700     /* A stat() call may fail for various reasons. If this happens, it is
  3682   3701     ** almost certain that an open() call on the same path will also fail.
  3683   3702     ** For this reason, if an error occurs in the stat() call here, it is
  3684   3703     ** ignored and -1 is returned. The caller will try to open a new file
  3685   3704     ** descriptor on the same path, fail, and return an error to SQLite.
  3686   3705     **
  3687   3706     ** Even if a subsequent open() call does succeed, the consequences of
  3688   3707     ** not searching for a resusable file descriptor are not dire.  */
  3689   3708     if( 0==stat(zPath, &sStat) ){
  3690         -    struct unixOpenCnt *p;
         3709  +    struct unixOpenCnt *pO;
  3691   3710       struct unixFileId id;
  3692   3711       id.dev = sStat.st_dev;
  3693   3712       id.ino = sStat.st_ino;
  3694   3713   
  3695   3714       unixEnterMutex();
  3696         -    for(p=openList; p&& memcmp(&id, &p->fileId, sizeof(id)); p=p->pNext);
  3697         -    if( p && p->aPending ){
  3698         -      int i;
  3699         -      struct PendingClose *aPending = p->aPending;
  3700         -      for(i=0; i<p->nPending; i++){
  3701         -        if( aPending[i].fd>=0 && flags==aPending[i].flags ){
  3702         -          fd = aPending[i].fd;
  3703         -          aPending[i].fd = -1;
  3704         -          break;
  3705         -        }
         3715  +    for(pO=openList; pO && memcmp(&id, &pO->fileId, sizeof(id)); pO=pO->pNext);
         3716  +    if( pO ){
         3717  +      UnixUnusedFd **pp;
         3718  +      for(pp=&pO->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
         3719  +      pUnused = *pp;
         3720  +      if( pUnused ){
         3721  +        *pp = pUnused->pNext;
  3706   3722         }
  3707   3723       }
  3708   3724       unixLeaveMutex();
  3709   3725     }
  3710         -
  3711         -  return fd;
         3726  +#endif    /* if !OS_VXWORKS */
         3727  +  return pUnused;
  3712   3728   }
  3713   3729   
  3714   3730   /*
  3715   3731   ** Open the file zPath.
  3716   3732   ** 
  3717   3733   ** Previously, the SQLite OS layer used three functions in place of this
  3718   3734   ** one:
................................................................................
  3792   3808          || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
  3793   3809          || eType==SQLITE_OPEN_TRANSIENT_DB
  3794   3810     );
  3795   3811   
  3796   3812     memset(p, 0, sizeof(unixFile));
  3797   3813   
  3798   3814     if( eType==SQLITE_OPEN_MAIN_DB ){
  3799         -    /* Try to find an unused file descriptor to reuse. This is not done
  3800         -    ** for vxworks. Not because vxworks would not benefit from the change
  3801         -    ** (it might, we're not sure), but because no way to test it is
  3802         -    ** currently available. It is better not to risk breaking vxworks for 
  3803         -    ** the sake of such an obscure feature.   */
  3804         -#if !OS_VXWORKS
  3805         -    fd = findReusableFd(zName, flags);
  3806         -#endif
         3815  +    UnixUnusedFd *pUnused;
         3816  +    pUnused = findReusableFd(zName, flags);
         3817  +    if( pUnused ){
         3818  +      fd = pUnused->fd;
         3819  +    }else{
         3820  +      pUnused = sqlite3_malloc(sizeof(pUnused));
         3821  +      if( !pUnused ){
         3822  +        return SQLITE_NOMEM;
         3823  +      }
         3824  +    }
         3825  +    p->pUnused = pUnused;
  3807   3826     }else if( !zName ){
  3808   3827       /* If zName is NULL, the upper layer is requesting a temp file. */
  3809   3828       assert(isDelete && !isOpenDirectory);
  3810   3829       rc = getTempname(MAX_PATHNAME+1, zTmpname);
  3811   3830       if( rc!=SQLITE_OK ){
  3812   3831         return rc;
  3813   3832       }
................................................................................
  3821   3840     if( isReadonly )  openFlags |= O_RDONLY;
  3822   3841     if( isReadWrite ) openFlags |= O_RDWR;
  3823   3842     if( isCreate )    openFlags |= O_CREAT;
  3824   3843     if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
  3825   3844     openFlags |= (O_LARGEFILE|O_BINARY);
  3826   3845   
  3827   3846     if( fd<0 ){
  3828         -    fd = open(zName, openFlags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
         3847  +    mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
         3848  +    fd = open(zName, openFlags, openMode);
  3829   3849       OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, openFlags);
  3830   3850       if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
  3831   3851         /* Failed to open the file for read/write access. Try read-only. */
  3832   3852         flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
         3853  +      openFlags &= ~(O_RDWR|O_CREAT);
  3833   3854         flags |= SQLITE_OPEN_READONLY;
  3834         -      return unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
         3855  +      openFlags |= O_RDONLY;
         3856  +      fd = open(zName, openFlags, openMode);
  3835   3857       }
  3836   3858       if( fd<0 ){
  3837         -      return SQLITE_CANTOPEN;
         3859  +      rc = SQLITE_CANTOPEN;
         3860  +      goto open_finished;
  3838   3861       }
  3839   3862     }
  3840   3863     assert( fd>=0 );
  3841         -  p->flags = flags;
  3842   3864     if( pOutFlags ){
  3843   3865       *pOutFlags = flags;
  3844   3866     }
         3867  +
         3868  +  if( p->pUnused ){
         3869  +    p->pUnused->fd = fd;
         3870  +    p->pUnused->flags = flags;
         3871  +  }
  3845   3872   
  3846   3873     if( isDelete ){
  3847   3874   #if OS_VXWORKS
  3848   3875       zPath = zName;
  3849   3876   #else
  3850   3877       unlink(zName);
  3851   3878   #endif
................................................................................
  3857   3884   #endif
  3858   3885   
  3859   3886     if( isOpenDirectory ){
  3860   3887       rc = openDirectory(zPath, &dirfd);
  3861   3888       if( rc!=SQLITE_OK ){
  3862   3889         /* It is safe to close fd at this point, because it is guaranteed not
  3863   3890         ** to be open on a database file. If it were open on a database file,
  3864         -      ** it would not be safe to close as this would cause any locks held
  3865         -      ** on the file by this process to be released.  */
         3891  +      ** it would not be safe to close as this would release any locks held
         3892  +      ** on the file by this process.  */
  3866   3893         assert( eType!=SQLITE_OPEN_MAIN_DB );
  3867   3894         close(fd);             /* silently leak if fail, already in error */
  3868         -      return rc;
         3895  +      goto open_finished;
  3869   3896       }
  3870   3897     }
  3871   3898   
  3872   3899   #ifdef FD_CLOEXEC
  3873   3900     fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
  3874   3901   #endif
  3875   3902   
................................................................................
  3883   3910       /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means 
  3884   3911       ** never use proxy, NULL means use proxy for non-local files only.  */
  3885   3912       if( envforce!=NULL ){
  3886   3913         useProxy = atoi(envforce)>0;
  3887   3914       }else{
  3888   3915         struct statfs fsInfo;
  3889   3916         if( statfs(zPath, &fsInfo) == -1 ){
  3890         -        ((unixFile*)pFile)->lastErrno = errno;
  3891         -        if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
         3917  +        /* In theory, the close(fd) call is sub-optimal. If the file opened
         3918  +        ** with fd is a database file, and there are other connections open
         3919  +        ** on that file that are currently holding advisory locks on it,
         3920  +        ** then the call to close() will cancel those locks. In practice,
         3921  +        ** we're assuming that statfs() doesn't fail very often. At least
         3922  +        ** not while other file descriptors opened by the same process on
         3923  +        ** the same file are working.  */
         3924  +        p->lastErrno = errno;
         3925  +        if( dirfd>=0 ){
         3926  +          close(dirfd); /* silently leak if fail, in error */
         3927  +        }
  3892   3928           close(fd); /* silently leak if fail, in error */
  3893         -        return SQLITE_IOERR_ACCESS;
         3929  +        rc = SQLITE_IOERR_ACCESS;
         3930  +        goto open_finished;
  3894   3931         }
  3895   3932         useProxy = !(fsInfo.f_flags&MNT_LOCAL);
  3896   3933       }
  3897   3934       if( useProxy ){
  3898   3935         rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
  3899   3936         if( rc==SQLITE_OK ){
  3900   3937           rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
  3901   3938         }
  3902         -      return rc;
         3939  +      goto open_finished;
  3903   3940       }
  3904   3941     }
  3905   3942   #endif
  3906   3943     
  3907         -  return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
         3944  +  rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
         3945  +open_finished:
         3946  +  if( rc!=SQLITE_OK ){
         3947  +    sqlite3_free(p->pUnused);
         3948  +  }
         3949  +  return rc;
  3908   3950   }
         3951  +
  3909   3952   
  3910   3953   /*
  3911   3954   ** Delete the file at zPath. If the dirSync argument is true, fsync()
  3912   3955   ** the directory after deleting the file.
  3913   3956   */
  3914   3957   static int unixDelete(
  3915   3958     sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */

Changes to test/tkt4018.test.

    39     39       CREATE TABLE t1(a, b);
    40     40       BEGIN;
    41     41       SELECT * FROM t1;
    42     42     }
    43     43   } {}
    44     44   
    45     45   # The database is locked by connection [db]. Open and close a second
    46         -# connection to test.db 20000 times. If file-descriptors are not being
           46  +# connection to test.db 10000 times. If file-descriptors are not being
    47     47   # reused, then the process will quickly exceed its maximum number of
    48     48   # file descriptors (1024 by default on linux).
    49     49   do_test tkt4018-1.2 {
    50     50     for {set i 0} {$i < 10000} {incr i} {
    51     51       sqlite3 db2 test.db
    52     52       db2 close
    53     53     }