mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Remove the xGetTempname() method from the vfs structure. Temp files are now opened by passing a NULL pointer as the filename to xOpen(). (CVS 5190)
FossilOrigin-Name: 5173b3e816c7eb711cd21a9068bbafb9ebb7cff1
This commit is contained in:
171
src/os_unix.c
171
src/os_unix.c
@@ -12,7 +12,7 @@
|
||||
**
|
||||
** This file contains code that is specific to Unix systems.
|
||||
**
|
||||
** $Id: os_unix.c,v 1.184 2008/06/05 11:39:11 danielk1977 Exp $
|
||||
** $Id: os_unix.c,v 1.185 2008/06/06 11:11:26 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#if OS_UNIX /* This file is used on unix only */
|
||||
@@ -2185,7 +2185,7 @@ static int fillInUnixFile(
|
||||
sqlite3_file *pId, /* Write to the unixFile structure here */
|
||||
const char *zFilename /* Name of the file being opened */
|
||||
){
|
||||
sqlite3LockingStyle lockingStyle;
|
||||
sqlite3LockingStyle lockingStyle = noLockingStyle;
|
||||
unixFile *pNew = (unixFile *)pId;
|
||||
int rc;
|
||||
|
||||
@@ -2193,24 +2193,28 @@ static int fillInUnixFile(
|
||||
fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
|
||||
if ( lockingStyle==posixLockingStyle ){
|
||||
enterMutex();
|
||||
rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
|
||||
leaveMutex();
|
||||
if( rc ){
|
||||
if( dirfd>=0 ) close(dirfd);
|
||||
close(h);
|
||||
return rc;
|
||||
assert( pNew->pLock==NULL );
|
||||
assert( pNew->pOpen==NULL );
|
||||
if( zFilename ){
|
||||
/* If zFilename is NULL then this is a temporary file. Temporary files
|
||||
** are never locked or unlocked, so noLockingStyle is used for these.
|
||||
** The locking style used by other files is determined by
|
||||
** sqlite3DetectLockingStyle().
|
||||
*/
|
||||
lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
|
||||
if ( lockingStyle==posixLockingStyle ){
|
||||
enterMutex();
|
||||
rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
|
||||
leaveMutex();
|
||||
if( rc ){
|
||||
if( dirfd>=0 ) close(dirfd);
|
||||
close(h);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* pLock and pOpen are only used for posix advisory locking */
|
||||
pNew->pLock = NULL;
|
||||
pNew->pOpen = NULL;
|
||||
}
|
||||
|
||||
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
||||
pNew->dirfd = -1;
|
||||
pNew->h = h;
|
||||
pNew->dirfd = dirfd;
|
||||
SET_THREADID(pNew);
|
||||
@@ -2336,6 +2340,63 @@ static int openDirectory(const char *zFilename, int *pFd){
|
||||
return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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,
|
||||
"/var/tmp",
|
||||
"/usr/tmp",
|
||||
"/tmp",
|
||||
".",
|
||||
};
|
||||
static const unsigned char zChars[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
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;
|
||||
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) >= nBuf ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
do{
|
||||
sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
|
||||
j = strlen(zBuf);
|
||||
sqlite3_randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
}while( access(zBuf,0)==0 );
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Open the file zPath.
|
||||
**
|
||||
@@ -2384,6 +2445,12 @@ static int unixOpen(
|
||||
(eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL)
|
||||
);
|
||||
|
||||
/* If argument zPath is a NULL pointer, this function is required to open
|
||||
** a temporary file. Use this buffer to store the file name in.
|
||||
*/
|
||||
char zTmpname[MAX_PATHNAME+1];
|
||||
const char *zName = zPath;
|
||||
|
||||
/* Check the following statements are true:
|
||||
**
|
||||
** (a) Exactly one of the READWRITE and READONLY flags must be set, and
|
||||
@@ -2411,6 +2478,16 @@ static int unixOpen(
|
||||
|| eType==SQLITE_OPEN_TRANSIENT_DB
|
||||
);
|
||||
|
||||
if( !zName ){
|
||||
int rc;
|
||||
assert(isDelete && !isOpenDirectory);
|
||||
rc = getTempname(MAX_PATHNAME+1, zTmpname);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
zName = zTmpname;
|
||||
}
|
||||
|
||||
if( isReadonly ) oflags |= O_RDONLY;
|
||||
if( isReadWrite ) oflags |= O_RDWR;
|
||||
if( isCreate ) oflags |= O_CREAT;
|
||||
@@ -2418,7 +2495,7 @@ static int unixOpen(
|
||||
oflags |= (O_LARGEFILE|O_BINARY);
|
||||
|
||||
memset(pFile, 0, sizeof(unixFile));
|
||||
fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||
fd = open(zName, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||
if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
|
||||
/* Failed to open the file for read/write access. Try read-only. */
|
||||
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||
@@ -2429,7 +2506,7 @@ static int unixOpen(
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
if( isDelete ){
|
||||
unlink(zPath);
|
||||
unlink(zName);
|
||||
}
|
||||
if( pOutFlags ){
|
||||
*pOutFlags = flags;
|
||||
@@ -2503,63 +2580,6 @@ static int unixAccess(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
static const char *azDirs[] = {
|
||||
0,
|
||||
"/var/tmp",
|
||||
"/usr/tmp",
|
||||
"/tmp",
|
||||
".",
|
||||
};
|
||||
static const unsigned char zChars[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
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_ERROR );
|
||||
|
||||
azDirs[0] = sqlite3_temp_directory;
|
||||
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) >= nBuf ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
do{
|
||||
assert( pVfs->mxPathname==MAX_PATHNAME );
|
||||
sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
|
||||
j = strlen(zBuf);
|
||||
sqlite3_randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
}while( access(zBuf,0)==0 );
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Turn a relative pathname into a full pathname. The relative path
|
||||
@@ -2773,7 +2793,6 @@ sqlite3_vfs *sqlite3OsDefaultVfs(void){
|
||||
unixOpen, /* xOpen */
|
||||
unixDelete, /* xDelete */
|
||||
unixAccess, /* xAccess */
|
||||
unixGetTempname, /* xGetTempName */
|
||||
unixFullPathname, /* xFullPathname */
|
||||
unixDlOpen, /* xDlOpen */
|
||||
unixDlError, /* xDlError */
|
||||
|
||||
Reference in New Issue
Block a user