diff options
author | drh <drh@noemail.net> | 2010-06-01 21:02:51 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2010-06-01 21:02:51 +0000 |
commit | 8b3cf82ddfb6e7897a970b14cd4e76ae2ee71268 (patch) | |
tree | 1423b35659eaebcb97633a87bd74b31b6460a9b5 /src | |
parent | 0235ab99446dcd772402e82c69871f6fc16b38ef (diff) | |
download | sqlite-8b3cf82ddfb6e7897a970b14cd4e76ae2ee71268.tar.gz sqlite-8b3cf82ddfb6e7897a970b14cd4e76ae2ee71268.zip |
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.
FossilOrigin-Name: fc18c4aadb908c3b6f9b6481a2efca6a0daadc64
Diffstat (limited to 'src')
-rw-r--r-- | src/os_unix.c | 84 | ||||
-rw-r--r-- | src/sqlite.h.in | 1 |
2 files changed, 58 insertions, 27 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 868071214..9d4a780a6 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3275,6 +3275,9 @@ static void unixShmPurge(unixFile *pFd){ } } +/* Forward reference */ +static const char *unixTempFileDir(int); + /* ** Open a shared-memory area. This particular implementation uses ** mmapped files. @@ -3297,7 +3300,9 @@ static int unixShmOpen( 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 */ + 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. */ @@ -3311,18 +3316,26 @@ static int unixShmOpen( ** one if present. Create a new one if necessary. */ unixEnterMutex(); - pShmNode = pDbFd->pInode->pShmNode; + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; if( pShmNode==0 ){ - nPath = strlen(pDbFd->zPath); - pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nPath + 15 ); + 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(nPath+15, pShmNode->zFilename, - "%s-wal-index", pDbFd->zPath); + 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; @@ -4199,26 +4212,54 @@ static int openDirectory(const char *zFilename, int *pFd){ } /* -** 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. +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. */ -static int getTempname(int nBuf, char *zBuf){ +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; - struct stat buf; - const char *zDir = "."; + 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 @@ -4226,19 +4267,8 @@ static int getTempname(int nBuf, char *zBuf){ */ 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; - } + 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. @@ -4428,7 +4458,7 @@ static int unixOpen( }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ assert(isDelete && !isOpenDirectory); - rc = getTempname(MAX_PATHNAME+1, zTmpname); + rc = unixGetTempname(MAX_PATHNAME+1, zTmpname); if( rc!=SQLITE_OK ){ return rc; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 0b931dcc9..e6a1659b9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -446,6 +446,7 @@ int sqlite3_exec( #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 |