aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-12-01 17:48:45 +0000
committerdrh <drh@noemail.net>2015-12-01 17:48:45 +0000
commit415afddaae95a60fea20b977b76eb6c86f902a40 (patch)
tree62e9a2a4675b38920fee00c81b88203428974a98 /src
parente1818ec7400a9917fbdbec566a70769b3fc94235 (diff)
parent92af1ebc75d8077c4885d02436e3630d7e91d473 (diff)
downloadsqlite-415afddaae95a60fea20b977b76eb6c86f902a40.tar.gz
sqlite-415afddaae95a60fea20b977b76eb6c86f902a40.zip
The test_fs.c test module now works on Windows.
FossilOrigin-Name: e3d8628456848a70035bbdeca6dc6c21f688b9a5
Diffstat (limited to 'src')
-rw-r--r--src/test_fs.c51
-rw-r--r--src/test_windirent.c157
-rw-r--r--src/test_windirent.h105
3 files changed, 304 insertions, 9 deletions
diff --git a/src/test_fs.c b/src/test_fs.c
index 213b65689..de332fa2f 100644
--- a/src/test_fs.c
+++ b/src/test_fs.c
@@ -73,9 +73,16 @@
#if SQLITE_OS_UNIX
# include <unistd.h>
# include <dirent.h>
+# ifndef DIRENT
+# define DIRENT dirent
+# endif
#endif
#if SQLITE_OS_WIN
# include <io.h>
+# include "test_windirent.h"
+# ifndef S_ISREG
+# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+# endif
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -116,7 +123,7 @@ struct FsdirCsr {
char *zDir; /* Buffer containing directory scanned */
DIR *pDir; /* Open directory */
sqlite3_int64 iRowid;
- struct dirent entry; /* Current entry */
+ struct DIRENT entry; /* Current entry */
};
/*
@@ -220,7 +227,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
FsdirCsr *pCsr = (FsdirCsr*)cur;
if( pCsr->pDir ){
- struct dirent *pRes = 0;
+ struct DIRENT *pRes = 0;
readdir_r(pCsr->pDir, &pCsr->entry, &pRes);
if( pRes==0 ){
closedir(pCsr->pDir);
@@ -461,15 +468,34 @@ static int fstreeFilter(
int rc;
const char *zSql =
"WITH r(d) AS ("
-" SELECT CASE WHEN dir='/' THEN '' ELSE dir END || '/' || name "
-" FROM fsdir WHERE dir=? AND name NOT LIKE '.%'"
+" SELECT CASE WHEN dir=?2 THEN ?3 ELSE dir END || '/' || name "
+" FROM fsdir WHERE dir=?1 AND name NOT LIKE '.%'"
" UNION ALL"
" SELECT dir || '/' || name FROM r, fsdir WHERE dir=d AND name NOT LIKE '.%'"
") SELECT d FROM r;";
- const char *zDir = "/";
- int nDir = 1;
- char aWild[2] = {'\0', '\0' };
+ char *zRoot;
+ int nRoot;
+ char *zPrefix;
+ int nPrefix;
+ const char *zDir;
+ int nDir;
+ char aWild[2] = { '\0', '\0' };
+
+#if SQLITE_OS_WIN
+ zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/');
+ nRoot = strlen(zRoot);
+ zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive"));
+ nPrefix = strlen(zPrefix);
+#else
+ zRoot = "/";
+ nRoot = 1;
+ zPrefix = "";
+ nPrefix = 0;
+#endif
+
+ zDir = zRoot;
+ nDir = nRoot;
fstreeCloseFd(pCsr);
sqlite3_finalize(pCsr->pStmt);
@@ -490,9 +516,9 @@ static int fstreeFilter(
break;
}
- if( zQuery[0]=='/' ){
+ if( sqlite3_strnicmp(zQuery, zPrefix, nPrefix)==0 ){
int i;
- for(i=1; zQuery[i]; i++){
+ for(i=nPrefix; zQuery[i]; i++){
if( zQuery[i]==aWild[0] || zQuery[i]==aWild[1] ) break;
if( zQuery[i]=='/' ) nDir = i;
}
@@ -501,6 +527,13 @@ static int fstreeFilter(
}
sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT);
+ sqlite3_bind_text(pCsr->pStmt, 2, zRoot, nRoot, SQLITE_TRANSIENT);
+ sqlite3_bind_text(pCsr->pStmt, 3, zPrefix, nPrefix, SQLITE_TRANSIENT);
+
+#if SQLITE_OS_WIN
+ sqlite3_free(zPrefix);
+ sqlite3_free(zRoot);
+#endif
return fstreeNext(pVtabCursor);
}
diff --git a/src/test_windirent.c b/src/test_windirent.c
new file mode 100644
index 000000000..11d7dc07d
--- /dev/null
+++ b/src/test_windirent.c
@@ -0,0 +1,157 @@
+/*
+** 2015 November 30
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code to implement most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+#include "test_windirent.h"
+
+/*
+** Implementation of the POSIX opendir() function using the MSVCRT.
+*/
+LPDIR opendir(
+ const char *dirname
+){
+ struct _finddata_t data;
+ LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
+ SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
+
+ if( dirp==NULL ) return NULL;
+ memset(dirp, 0, sizeof(DIR));
+
+ /* TODO: Remove this if Unix-style root paths are not used. */
+ if( sqlite3_stricmp(dirname, "/")==0 ){
+ dirname = getenv("SystemDrive");
+ }
+
+ _snprintf(data.name, namesize, "%s\\*", dirname);
+ dirp->d_handle = _findfirst(data.name, &data);
+
+ if( dirp->d_handle==BAD_INTPTR_T ){
+ closedir(dirp);
+ return NULL;
+ }
+
+ /* TODO: Remove this block to allow hidden and system files. */
+ if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){
+ if( _findnext(dirp->d_handle, &data)==-1 ){
+ closedir(dirp);
+ return NULL;
+ }
+ }
+
+ dirp->d_first.d_attributes = data.attrib;
+ strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
+ dirp->d_first.d_name[NAME_MAX] = '\0';
+
+ return dirp;
+}
+
+/*
+** Implementation of the POSIX readdir() function using the MSVCRT.
+*/
+LPDIRENT readdir(
+ LPDIR dirp
+){
+ struct _finddata_t data;
+
+ if( dirp==NULL ) return NULL;
+
+ if( dirp->d_first.d_ino==0 ){
+ dirp->d_first.d_ino++;
+ dirp->d_next.d_ino++;
+
+ return &dirp->d_first;
+ }
+
+next:
+
+ if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
+
+ /* TODO: Remove this block to allow hidden and system files. */
+ if( data.attrib&_A_HIDDEN ) goto next;
+ if( data.attrib&_A_SYSTEM ) goto next;
+
+ dirp->d_next.d_ino++;
+ dirp->d_next.d_attributes = data.attrib;
+ strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
+ dirp->d_next.d_name[NAME_MAX] = '\0';
+
+ return &dirp->d_next;
+}
+
+/*
+** Implementation of the POSIX readdir_r() function using the MSVCRT.
+*/
+INT readdir_r(
+ LPDIR dirp,
+ LPDIRENT entry,
+ LPDIRENT *result
+){
+ struct _finddata_t data;
+
+ if( dirp==NULL ) return EBADF;
+
+ if( dirp->d_first.d_ino==0 ){
+ dirp->d_first.d_ino++;
+ dirp->d_next.d_ino++;
+
+ entry->d_ino = dirp->d_first.d_ino;
+ entry->d_attributes = dirp->d_first.d_attributes;
+ strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
+ entry->d_name[NAME_MAX] = '\0';
+
+ *result = entry;
+ return 0;
+ }
+
+next:
+
+ if( _findnext(dirp->d_handle, &data)==-1 ){
+ *result = NULL;
+ return ENOENT;
+ }
+
+ /* TODO: Remove this block to allow hidden and system files. */
+ if( data.attrib&_A_HIDDEN ) goto next;
+ if( data.attrib&_A_SYSTEM ) goto next;
+
+ entry->d_ino = (ino_t)-1; /* not available */
+ entry->d_attributes = data.attrib;
+ strncpy(entry->d_name, data.name, NAME_MAX);
+ entry->d_name[NAME_MAX] = '\0';
+
+ *result = entry;
+ return 0;
+}
+
+/*
+** Implementation of the POSIX closedir() function using the MSVCRT.
+*/
+INT closedir(
+ LPDIR dirp
+){
+ INT result = 0;
+
+ if( dirp==NULL ) return EINVAL;
+
+ if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
+ result = _findclose(dirp->d_handle);
+ }
+
+ sqlite3_free(dirp);
+ return result;
+}
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */
diff --git a/src/test_windirent.h b/src/test_windirent.h
new file mode 100644
index 000000000..0b8d1a7b5
--- /dev/null
+++ b/src/test_windirent.h
@@ -0,0 +1,105 @@
+/*
+** 2015 November 30
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains declarations for most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+/*
+** We need several data types from the Windows SDK header.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+
+/*
+** We need several support functions from the SQLite core.
+*/
+
+#include "sqlite3.h"
+
+/*
+** We need several things from the ANSI and MSVCRT headers.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <io.h>
+#include <limits.h>
+
+/*
+** We may need to provide the "ino_t" type.
+*/
+
+#ifndef INO_T_DEFINED
+ #define INO_T_DEFINED
+ typedef unsigned short ino_t;
+#endif
+
+/*
+** We need to define "NAME_MAX" if it was not present in "limits.h".
+*/
+
+#ifndef NAME_MAX
+# ifdef FILENAME_MAX
+# define NAME_MAX (FILENAME_MAX)
+# else
+# define NAME_MAX (260)
+# endif
+#endif
+
+/*
+** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
+*/
+
+#ifndef NULL_INTPTR_T
+# define NULL_INTPTR_T ((intptr_t)(0))
+#endif
+
+#ifndef BAD_INTPTR_T
+# define BAD_INTPTR_T ((intptr_t)(-1))
+#endif
+
+/*
+** We need to provide the necessary structures and related types.
+*/
+
+typedef struct DIRENT DIRENT;
+typedef struct DIR DIR;
+typedef DIRENT *LPDIRENT;
+typedef DIR *LPDIR;
+
+struct DIRENT {
+ ino_t d_ino; /* Sequence number, do not use. */
+ unsigned d_attributes; /* Win32 file attributes. */
+ char d_name[NAME_MAX + 1]; /* Name within the directory. */
+};
+
+struct DIR {
+ intptr_t d_handle; /* Value returned by "_findfirst". */
+ DIRENT d_first; /* DIRENT constructed based on "_findfirst". */
+ DIRENT d_next; /* DIRENT constructed based on "_findnext". */
+};
+
+/*
+** Finally, we can provide the function prototypes for the opendir(),
+** readdir(), readdir_r(), and closedir() POSIX functions.
+*/
+
+extern LPDIR opendir(const char *dirname);
+extern LPDIRENT readdir(LPDIR dirp);
+extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
+extern INT closedir(LPDIR dirp);
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */