aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c6
-rw-r--r--src/os_win.c4
-rw-r--r--src/shell.c13
-rw-r--r--src/sqlite.h.in12
-rw-r--r--src/test1.c34
-rw-r--r--src/test_multiplex.c3
-rw-r--r--src/test_osinst.c6
-rw-r--r--src/test_quota.c6
-rw-r--r--src/test_vfstrace.c8
9 files changed, 90 insertions, 2 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index ecd5bf244..3cb28b058 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -206,6 +206,7 @@ struct UnixUnusedFd {
typedef struct unixFile unixFile;
struct unixFile {
sqlite3_io_methods const *pMethod; /* Always the first entry */
+ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */
unixInodeInfo *pInode; /* Info about locks on this inode */
int h; /* The file descriptor */
unsigned char eFileLock; /* The type of lock held on this fd */
@@ -3533,6 +3534,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
+ case SQLITE_FCNTL_VFSNAME: {
+ *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
+ return SQLITE_OK;
+ }
#ifndef NDEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
@@ -4560,6 +4565,7 @@ static int fillInUnixFile(
OSTRACE(("OPEN %-3d %s\n", h, zFilename));
pNew->h = h;
+ pNew->pVfs = pVfs;
pNew->zPath = zFilename;
if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
pNew->ctrlFlags = UNIXFILE_EXCL;
diff --git a/src/os_win.c b/src/os_win.c
index 62868ba50..53cf52353 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -2145,6 +2145,10 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
+ case SQLITE_FCNTL_VFSNAME: {
+ *(char**)pArg = sqlite3_mprintf("win32");
+ return SQLITE_OK;
+ }
case SQLITE_FCNTL_SYNC_OMITTED: {
return SQLITE_OK;
}
diff --git a/src/shell.c b/src/shell.c
index 07b1b60b4..503d8a6a8 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1396,6 +1396,7 @@ static char zHelp[] =
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
".timeout MS Try opening locked tables for MS milliseconds\n"
+ ".vfsname ?AUX? Print the name of the VFS stack\n"
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
;
@@ -2339,6 +2340,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_libversion(), sqlite3_sourceid());
}else
+ if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
+ const char *zDbName = nArg==2 ? azArg[1] : "main";
+ char *zVfsName = 0;
+ if( p->db ){
+ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
+ if( zVfsName ){
+ printf("%s\n", zVfsName);
+ sqlite3_free(zVfsName);
+ }
+ }
+ }else
+
if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
int j;
assert( nArg<=ArraySize(azArg) );
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 75241da42..553372803 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -771,6 +771,17 @@ struct sqlite3_io_methods {
** a write transaction to indicate that, unless it is rolled back for some
** reason, the entire database file will be overwritten by the current
** transaction. This is used by VACUUM operations.
+**
+** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
+** all [VFSes] in the VFS stack. The names are of all VFS shims and the
+** final bottom-level VFS are written into memory obtained from
+** [sqlite3_malloc()] and the result is stored in the char* variable
+** that the fourth parameter of [sqlite3_file_control()] points to.
+** The caller is responsible for freeing the memory when done. As with
+** all file-control actions, there is no guarantee that this will actually
+** do anything. Callers should initialize the char* variable to a NULL
+** pointer in case this file-control is not implemented. This file-control
+** is intended for diagnostic use only.
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2
@@ -783,6 +794,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_WIN32_AV_RETRY 9
#define SQLITE_FCNTL_PERSIST_WAL 10
#define SQLITE_FCNTL_OVERWRITE 11
+#define SQLITE_FCNTL_VFSNAME 12
/*
** CAPI3REF: Mutex Handle
diff --git a/src/test1.c b/src/test1.c
index 3cf9b1375..3c6874368 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -5210,6 +5210,39 @@ static int file_control_persist_wal(
/*
+** tclcmd: file_control_vfsname DB ?AUXDB?
+**
+** Return a string that describes the stack of VFSes.
+*/
+static int file_control_vfsname(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ sqlite3 *db;
+ const char *zDbName = "main";
+ char *zVfsName = 0;
+
+ if( objc!=2 && objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ if( objc==3 ){
+ zDbName = Tcl_GetString(objv[2]);
+ }
+ sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
+ Tcl_AppendResult(interp, zVfsName, (char*)0);
+ sqlite3_free(zVfsName);
+ return TCL_OK;
+}
+
+
+/*
** tclcmd: sqlite3_vfs_list
**
** Return a tcl list containing the names of all registered vfs's.
@@ -6032,6 +6065,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_sizehint_test", file_control_sizehint_test, 0 },
{ "file_control_win32_av_retry", file_control_win32_av_retry, 0 },
{ "file_control_persist_wal", file_control_persist_wal, 0 },
+ { "file_control_vfsname", file_control_vfsname, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },
diff --git a/src/test_multiplex.c b/src/test_multiplex.c
index c4aeca81b..f6540d82d 100644
--- a/src/test_multiplex.c
+++ b/src/test_multiplex.c
@@ -856,6 +856,9 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
if( pSubOpen ){
rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
+ if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
+ *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg);
+ }
}
break;
}
diff --git a/src/test_osinst.c b/src/test_osinst.c
index 50d6250e6..b7f350577 100644
--- a/src/test_osinst.c
+++ b/src/test_osinst.c
@@ -389,7 +389,11 @@ static int vfslogCheckReservedLock(sqlite3_file *pFile, int *pResOut){
*/
static int vfslogFileControl(sqlite3_file *pFile, int op, void *pArg){
VfslogFile *p = (VfslogFile *)pFile;
- return p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
+ int rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
+ if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
+ *(char**)pArg = sqlite3_mprintf("vfslog/%z", *(char**)pArg);
+ }
+ return rc;
}
/*
diff --git a/src/test_quota.c b/src/test_quota.c
index 74d1a6d3b..9aad4967b 100644
--- a/src/test_quota.c
+++ b/src/test_quota.c
@@ -589,7 +589,11 @@ static int quotaCheckReservedLock(sqlite3_file *pConn, int *pResOut){
*/
static int quotaFileControl(sqlite3_file *pConn, int op, void *pArg){
sqlite3_file *pSubOpen = quotaSubOpen(pConn);
- return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
+ int rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
+ if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
+ *(char**)pArg = sqlite3_mprintf("quota/%z", *(char**)pArg);
+ }
+ return rc;
}
/* Pass xSectorSize requests through to the original VFS unchanged.
diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c
index 5e94f5cf0..62577207b 100644
--- a/src/test_vfstrace.c
+++ b/src/test_vfstrace.c
@@ -471,6 +471,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
}
case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break;
case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break;
+ case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break;
+ case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break;
+ case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
+ case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
default: {
sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
@@ -482,6 +486,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
pInfo->zVfsName, p->zFName, zOp);
rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
+ if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
+ *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
+ pInfo->zVfsName, *(char**)pArg);
+ }
return rc;
}