SQLite

Check-in [fc18c4aadb]
Login

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

Overview
Comment:The shared-memory used by WAL on linux now really is shared memory in /dev/shm. On other unix flavors, the file is in a temporary directory rather than in the same directory as the database.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fc18c4aadb908c3b6f9b6481a2efca6a0daadc64
User & Date: drh 2010-06-01 21:02:52.000
Context
2010-06-02
05:53
Add some 'const' markers to static data that is really constant. (check-in: e7073e23b8 user: dan tags: trunk)
2010-06-01
21:02
The shared-memory used by WAL on linux now really is shared memory in /dev/shm. On other unix flavors, the file is in a temporary directory rather than in the same directory as the database. (check-in: fc18c4aadb user: drh tags: trunk)
19:15
Changes to the way faults are injected into xShmXXX VFS calls. (check-in: 716d99f392 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
3271
3272
3273
3274
3275
3276
3277



3278
3279
3280
3281
3282
3283
3284
    if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf);
    if( p->h>=0 ) close(p->h);
    p->pInode->pShmNode = 0;
    sqlite3_free(p);
  }
}




/*
** Open a shared-memory area.  This particular implementation uses
** mmapped files.
**
** zName is a filename used to identify the shared-memory area.  The
** implementation does not (and perhaps should not) use this name
** directly, but rather use it as a template for finding an appropriate







>
>
>







3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
    if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf);
    if( p->h>=0 ) close(p->h);
    p->pInode->pShmNode = 0;
    sqlite3_free(p);
  }
}

/* Forward reference */
static const char *unixTempFileDir(int);

/*
** Open a shared-memory area.  This particular implementation uses
** mmapped files.
**
** zName is a filename used to identify the shared-memory area.  The
** implementation does not (and perhaps should not) use this name
** directly, but rather use it as a template for finding an appropriate
3293
3294
3295
3296
3297
3298
3299


3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314

3315






3316
3317
3318
3319
3320
3321
3322
3323
3324
3325

3326
3327
3328
3329
3330
3331
3332
static int unixShmOpen(
  sqlite3_file *fd      /* The file descriptor of the associated database */
){
  struct unixShm *p = 0;             /* The connection to be opened */
  struct unixShmNode *pShmNode = 0;  /* The underlying mmapped file */
  int rc;                            /* Result code */
  struct unixFile *pDbFd;            /* Underlying database file */


  int nPath;                         /* Size of pDbFd->zPath in bytes */

  /* Allocate space for the new sqlite3_shm object.
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  pDbFd = (struct unixFile*)fd;
  assert( pDbFd->pShm==0 );

  /* Check to see if a unixShmNode object already exists.  Reuse an existing
  ** one if present.  Create a new one if necessary.
  */
  unixEnterMutex();
  pShmNode = pDbFd->pInode->pShmNode;

  if( pShmNode==0 ){






    nPath = strlen(pDbFd->zPath);
    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nPath + 15 );
    if( pShmNode==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
    }
    memset(pShmNode, 0, sizeof(*pShmNode));
    pShmNode->zFilename = (char*)&pShmNode[1];
    sqlite3_snprintf(nPath+15, pShmNode->zFilename,
                     "%s-wal-index", pDbFd->zPath);

    pShmNode->h = -1;
    pDbFd->pInode->pShmNode = pShmNode;
    pShmNode->pInode = pDbFd->pInode;
    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pShmNode->mutex==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;







>
>
|













|
>

>
>
>
>
>
>
|
|






|
|
>







3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
static int unixShmOpen(
  sqlite3_file *fd      /* The file descriptor of the associated database */
){
  struct unixShm *p = 0;             /* The connection to be opened */
  struct unixShmNode *pShmNode = 0;  /* The underlying mmapped file */
  int rc;                            /* Result code */
  struct unixFile *pDbFd;            /* Underlying database file */
  unixInodeInfo *pInode;             /* The inode of fd */
  const char *zTempDir;              /* Directory for temporary files */
  int nTempDir;                      /* Size of the zTempDir string */

  /* Allocate space for the new sqlite3_shm object.
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  pDbFd = (struct unixFile*)fd;
  assert( pDbFd->pShm==0 );

  /* Check to see if a unixShmNode object already exists.  Reuse an existing
  ** one if present.  Create a new one if necessary.
  */
  unixEnterMutex();
  pInode = pDbFd->pInode;
  pShmNode = pInode->pShmNode;
  if( pShmNode==0 ){
    zTempDir = unixTempFileDir(1);
    if( zTempDir==0 ){
      unixLeaveMutex();
      sqlite3_free(p);
      return SQLITE_CANTOPEN_NOTEMPDIR;
    }
    nTempDir = strlen(zTempDir);
    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nTempDir + 50 );
    if( pShmNode==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
    }
    memset(pShmNode, 0, sizeof(*pShmNode));
    pShmNode->zFilename = (char*)&pShmNode[1];
    sqlite3_snprintf(nTempDir+50, pShmNode->zFilename,
                     "%s/sqlite-wi-%x-%x", zTempDir,
                     (u32)pInode->fileId.dev, (u32)pInode->fileId.ino);
    pShmNode->h = -1;
    pDbFd->pInode->pShmNode = pShmNode;
    pShmNode->pInode = pDbFd->pInode;
    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pShmNode->mutex==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
4195
4196
4197
4198
4199
4200
4201

4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213

4214






























4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
    }
  }
  *pFd = fd;
  return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT);
}

/*

** Create a temporary file name in zBuf.  zBuf must be allocated
** by the calling process and must be big enough to hold at least
** pVfs->mxPathname bytes.
*/
static int getTempname(int nBuf, char *zBuf){
  static const char *azDirs[] = {
     0,
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     ".",

  };






























  static const unsigned char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  unsigned int i, j;
  struct stat buf;
  const char *zDir = ".";

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. 
  */
  SimulateIOError( return SQLITE_IOERR );

  azDirs[0] = sqlite3_temp_directory;
  if (NULL == azDirs[1]) {
    azDirs[1] = getenv("TMPDIR");
  }
  
  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
    if( azDirs[i]==0 ) continue;
    if( stat(azDirs[i], &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( access(azDirs[i], 07) ) continue;
    zDir = azDirs[i];
    break;
  }

  /* Check that the output buffer is large enough for the temporary file 
  ** name. If it is not, return SQLITE_ERROR.
  */
  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){
    return SQLITE_ERROR;
  }







>
|
<
<

|






<
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
|







<
<
<
<
|
<
<
<
<
<
|
<
<







4208
4209
4210
4211
4212
4213
4214
4215
4216


4217
4218
4219
4220
4221
4222
4223
4224

4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261

4262
4263
4264
4265
4266
4267
4268
4269




4270





4271


4272
4273
4274
4275
4276
4277
4278
    }
  }
  *pFd = fd;
  return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT);
}

/*
** Return the name of a directory in which to put temporary files.
** If no suitable temporary file directory can be found, return NULL.


*/
static const char *unixTempFileDir(int allowShm){
  static const char *azDirs[] = {
     0,
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",

     0        /* List terminator */
  };
  unsigned int i;
  struct stat buf;
  const char *zDir = 0;

  azDirs[0] = sqlite3_temp_directory;
  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
  
  if( allowShm ){
    zDir = "/dev/shm";
    i = 0;
  }else{
    zDir = azDirs[0];
    i = 1;
  }
  for(; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
    if( zDir==0 ) continue;
    if( stat(zDir, &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( access(zDir, 07) ) continue;
    break;
  }
  return zDir;
}

/*
** Create a temporary file name in zBuf.  zBuf must be allocated
** by the calling process and must be big enough to hold at least
** pVfs->mxPathname bytes.
*/
static int unixGetTempname(int nBuf, char *zBuf){
  static const unsigned char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  unsigned int i, j;

  const char *zDir;

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. 
  */
  SimulateIOError( return SQLITE_IOERR );





  zDir = unixTempFileDir(0);





  if( zDir==0 ) zDir = ".";



  /* Check that the output buffer is large enough for the temporary file 
  ** name. If it is not, return SQLITE_ERROR.
  */
  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){
    return SQLITE_ERROR;
  }
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
        return SQLITE_NOMEM;
      }
    }
    p->pUnused = pUnused;
  }else if( !zName ){
    /* If zName is NULL, the upper layer is requesting a temp file. */
    assert(isDelete && !isOpenDirectory);
    rc = getTempname(MAX_PATHNAME+1, zTmpname);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    zName = zTmpname;
  }

  /* Determine the value of the flags parameter passed to POSIX function







|







4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
        return SQLITE_NOMEM;
      }
    }
    p->pUnused = pUnused;
  }else if( !zName ){
    /* If zName is NULL, the upper layer is requesting a temp file. */
    assert(isDelete && !isOpenDirectory);
    rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    zName = zTmpname;
  }

  /* Determine the value of the flags parameter passed to POSIX function
Changes to src/sqlite.h.in.
442
443
444
445
446
447
448

449
450
451
452
453
454
455
#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))


/*
** CAPI3REF: Flags For File Open Operations
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the xOpen method of the







>







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))

/*
** CAPI3REF: Flags For File Open Operations
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the xOpen method of the