summaryrefslogtreecommitdiff
path: root/components/external/SQLite-3.8.1/src/os_rtthread.c
diff options
context:
space:
mode:
authorbernard <[email protected]>2017-11-02 13:50:42 +0800
committerbernard <[email protected]>2017-11-02 13:50:42 +0800
commitb2057f506a09e2adef81fc77efd697d16ae14bec (patch)
tree3affefabfe376a0ec1b3ac4a5eef957c1dd58dc8 /components/external/SQLite-3.8.1/src/os_rtthread.c
parent23582c8129228b4961ad35319cfd2d270039345f (diff)
[External] Remove external from RT-Thread
Diffstat (limited to 'components/external/SQLite-3.8.1/src/os_rtthread.c')
-rw-r--r--components/external/SQLite-3.8.1/src/os_rtthread.c2718
1 files changed, 0 insertions, 2718 deletions
diff --git a/components/external/SQLite-3.8.1/src/os_rtthread.c b/components/external/SQLite-3.8.1/src/os_rtthread.c
deleted file mode 100644
index 6d57ed7098..0000000000
--- a/components/external/SQLite-3.8.1/src/os_rtthread.c
+++ /dev/null
@@ -1,2718 +0,0 @@
-/*
-** 2004 May 22
-**
-** 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 that is specific to Windows.
-*/
-#include "sqliteInt.h"
-#if SQLITE_OS_RTTHREAD /* This file is used for rt-thread only */
-
-#include <rtthread.h>
-#include <dfs_posix.h>
-
-/*
-** Include code that is common to all os_*.c files
-*/
-#include "os_common.h"
-
-#ifndef RT_USING_NEWLIB
-
-#ifndef EINTR
-#define EINTR 4 /* Interrupted system call */
-#endif
-
-#ifndef ENOLCK
-#define ENOLCK 46 /* No record locks available */
-#endif
-
-#ifndef EACCES
-#define EACCES 13 /* Permission denied */
-#endif
-
-#ifndef EPERM
-#define EPERM 1 /* Operation not permitted */
-#endif
-
-#ifndef ETIMEDOUT
-#define ETIMEDOUT 145 /* Connection timed out */
-#endif
-
-#ifndef ENOTCONN
-#define ENOTCONN 134 /* Transport endpoint is not connected */
-#endif
-
-#if defined(__GNUC__) || defined(__ADSPBLACKFIN__)
-int _gettimeofday(struct timeval *tp, void *ignore) __attribute__((weak));
-int _gettimeofday(struct timeval *tp, void *ignore)
-#elif defined(__CC_ARM)
-__weak int _gettimeofday(struct timeval *tp, void *ignore)
-#elif defined(__IAR_SYSTEMS_ICC__)
- #if __VER__ > 540
- __weak
- #endif
-int _gettimeofday(struct timeval *tp, void *ignore)
-#else
-int _gettimeofday(struct timeval *tp, void *ignore)
-#endif
-{
- return 0;
-}
-
-#endif /* RT_USING_NEWLIB */
-
-/*
-** Compiling and using WAL mode requires several APIs that are not
-** available in rt-thread.
-*/
-#if !defined(SQLITE_OMIT_WAL)
-# error "WAL mode requires not support from the rt-thread, compile\
- with SQLITE_OMIT_WAL."
-#endif
-
-/*
-** Are most of the rtthread ANSI APIs available (i.e. with certain exceptions
-** based on the sub-platform)?
-*/
-#if !defined(SQLITE_RTTHREAD_NO_ANSI)
-# warning "please ensure rtthread ANSI APIs is available, otherwise compile with\
- SQLITE_RTTHREAD_NO_ANSI"
-# define SQLITE_RTTHREAD_HAS_ANSI
-#endif
-
-/*
-** Are most of the rtthread Unicode APIs available (i.e. with certain exceptions
-** based on the sub-platform)?
-*/
-#if !defined(SQLITE_RTTHREAD_NO_WIDE)
-# error "rtthread not support Unicode APIs"
-# define SQLITE_RTTHREAD_HAS_WIDE
-#endif
-
-/*
-** Make sure at least one set of rtthread APIs is available.
-*/
-#if !defined(SQLITE_RTTHREAD_HAS_ANSI) && !defined(SQLITE_RTTHREAD_HAS_WIDE)
-# error "At least one of SQLITE_RTTHREAD_HAS_ANSI and SQLITE_RTTHREAD_HAS_WIDE\
- must be defined."
-#endif
-
-/*
-** Maximum pathname length (in chars) for rtthread. This should normally be
-** MAX_PATH.
-*/
-#ifndef SQLITE_RTTHREAD_MAX_PATH_CHARS
-# warning "default Maximum pathname length be 255, otherwise compile with\
- SQLITE_RTTHREAD_MAX_PATH_CHARS=?"
-# define SQLITE_RTTHREAD_MAX_PATH_CHARS (255)
-#endif
-
-/*
-** Maximum supported path-length.
-*/
-#define MAX_PATHNAME 512
-
-/*
-** Returns non-zero if the character should be treated as a directory
-** separator.
-*/
-#ifndef rtthreadIsDirSep
-# define rtthreadIsDirSep(a) ((a) == '/')
-#endif
-
-/*
-** This macro is used when a local variable is set to a value that is
-** [sometimes] not used by the code (e.g. via conditional compilation).
-*/
-#ifndef UNUSED_VARIABLE_VALUE
-# define UNUSED_VARIABLE_VALUE(x) (void)(x)
-#endif
-
-/*
-** Returns the string that should be used as the directory separator.
-*/
-#ifndef rtthreadGetDirDep
-# define rtthreadGetDirDep() "/"
-#endif
-
-/*
-** The winFile structure is a subclass of sqlite3_file* specific to the win32
-** portability layer.
-*/
-typedef struct rtthreadFile rtthreadFile;
-struct rtthreadFile {
- sqlite3_io_methods const *pMethod; /* Always the first entry */
- sqlite3_vfs *pVfs; /* The VFS that created this rtthreadFile */
- int h; /* The file descriptor */
- unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
- unsigned char eFileLock; /* The type of lock held on this fd */
- int lastErrno; /* The unix errno from last I/O error */
- void *lockingContext; /* Locking style specific state */
- const char *zPath; /* Name of the file */
- int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
-#if SQLITE_ENABLE_LOCKING_STYLE
- int openFlags; /* The flags specified at open() */
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- unsigned fsFlags; /* cached details from statfs() */
-#endif
-#ifdef SQLITE_DEBUG
- /* The next group of variables are used to track whether or not the
- ** transaction counter in bytes 24-27 of database files are updated
- ** whenever any part of the database changes. An assertion fault will
- ** occur if a file is updated without also updating the transaction
- ** counter. This test is made to avoid new problems similar to the
- ** one described by ticket #3584.
- */
- unsigned char transCntrChng; /* True if the transaction counter changed */
- unsigned char dbUpdate; /* True if any part of database file changed */
- unsigned char inNormalWrite; /* True if in a normal write operation */
-
-#endif
-
-#ifdef SQLITE_TEST
- /* In test mode, increase the size of this structure a bit so that
- ** it is larger than the struct CrashFile defined in test6.c.
- */
- char aPadding[32];
-#endif
-};
-
-/*
-** Allowed values for the rtthreadFile.ctrlFlags bitmask:
-*/
-#define UNIXFILE_EXCL 0x01 /* Connections from one process only */
-#define UNIXFILE_RDONLY 0x02 /* Connection is read only */
-#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
-#ifndef SQLITE_DISABLE_DIRSYNC
-# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
-#else
-# define UNIXFILE_DIRSYNC 0x00
-#endif
-#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-#define UNIXFILE_DELETE 0x20 /* Delete on close */
-#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
-#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
-#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
-
-/*
-** The following variable is (normally) set once and never changes
-** thereafter. It records whether the operating system is Win9x
-** or WinNT.
-**
-** 0: Operating system unknown.
-** 1: Operating system is rtthread.
-**
-** In order to facilitate testing on a rtthread system, the test fixture
-** can manually set this value to 1 to emulate Win98 behavior.
-*/
-#ifdef SQLITE_TEST
-int sqlite3_os_type = 0;
-#elif !SQLITE_OS_RTTHREAD && \
- defined(SQLITE_RTTHREAD_HAS_ANSI) && defined(SQLITE_RTTHREAD_HAS_WIDE)
-static int sqlite3_os_type = 0;
-#endif
-
-#ifndef SYSCALL
-# define SYSCALL sqlite3_syscall_ptr
-#endif
-
-#include <dfs_posix.h>
-
-static int _Access(const char *pathname, int mode)
-{
- int fd;
-
- fd = open(pathname, O_RDONLY, mode);
-
- if (fd >= 0)
- {
- close(fd);
- return 0;
- }
-
- return -1;
-}
-
-/*
-** Invoke open(). Do so multiple times, until it either succeeds or
-** fails for some reason other than EINTR.
-**
-** If the file creation mode "m" is 0 then set it to the default for
-** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
-** 0644) as modified by the system umask. If m is not 0, then
-** make the file creation mode be exactly m ignoring the umask.
-**
-** The m parameter will be non-zero only when creating -wal, -journal,
-** and -shm files. We want those files to have *exactly* the same
-** permissions as their original database, unadulterated by the umask.
-** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
-** transaction crashes and leaves behind hot journals, then any
-** process that is able to write to the database will also be able to
-** recover the hot journals.
-*/
-static int robust_open(const char *z, int f, mode_t m);
-
-/*
-** Open a file descriptor to the directory containing file zFilename.
-** If successful, *pFd is set to the opened file descriptor and
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-** value.
-**
-** The directory file descriptor is used for only one thing - to
-** fsync() a directory to make sure file creation and deletion events
-** are flushed to disk. Such fsyncs are not needed on newer
-** journaling filesystems, but are required on older filesystems.
-**
-** This routine can be overridden using the xSetSysCall interface.
-** The ability to override this routine was added in support of the
-** chromium sandbox. Opening a directory is a security risk (we are
-** told) so making it overrideable allows the chromium sandbox to
-** replace this routine with a harmless no-op. To make this routine
-** a no-op, replace it with a stub that returns SQLITE_OK but leaves
-** *pFd set to a negative number.
-**
-** If SQLITE_OK is returned, the caller is responsible for closing
-** the file descriptor *pFd using close().
-*/
-static int openDirectory(const char *zFilename, int *pFd);
-
-/*
-** Many system calls are accessed through pointer-to-functions so that
-** they may be overridden at runtime to facilitate fault injection during
-** testing and sandboxing. The following array holds the names and pointers
-** to all overrideable system calls.
-*/
-static struct rtthread_syscall {
- const char *zName; /* Name of the system call */
- sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
- sqlite3_syscall_ptr pDefault; /* Default value */
-} aSyscall[] = {
- {"sleep", (sqlite3_syscall_ptr)rt_thread_delay, 0},
-#define osSleep ((rt_err_t(*)(rt_tick_t))aSyscall[0].pCurrent)
-
- { "open", (sqlite3_syscall_ptr)open, 0 },
-#define osOpen ((int(*)(const char*,int,int))aSyscall[1].pCurrent)
-
- { "close", (sqlite3_syscall_ptr)close, 0 },
-#define osClose ((int(*)(int))aSyscall[2].pCurrent)
-
- { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 },
-#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent)
-
- { "stat", (sqlite3_syscall_ptr)stat, 0 },
-#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)
-
- { "fstat", (sqlite3_syscall_ptr)fstat, 0 },
-#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
-
- { "read", (sqlite3_syscall_ptr)read, 0 },
-#define osRead ((int(*)(int,void*,size_t))aSyscall[6].pCurrent)
-
- { "write", (sqlite3_syscall_ptr)write, 0 },
-#define osWrite ((int(*)(int,const void*,size_t))aSyscall[7].pCurrent)
-
- { "unlink", (sqlite3_syscall_ptr)unlink, 0 },
-#define osUnlink ((int(*)(const char*))aSyscall[8].pCurrent)
-
- { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 },
-#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[9].pCurrent)
-
- { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
-#define osMkdir ((int(*)(const char*,mode_t))aSyscall[10].pCurrent)
-
- { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
-#define osRmdir ((int(*)(const char*))aSyscall[11].pCurrent)
-
- {"access", (sqlite3_syscall_ptr)_Access, 0 },
-#define osAccess ((int(*)(const char*, int))aSyscall[12].pCurrent)
-}; /* End of the overrideable system calls */
-
-/*
-**
-** This function - unixLogError_x(), is only ever called via the macro
-** unixLogError().
-**
-** It is invoked after an error occurs in an OS function and errno has been
-** set. It logs a message using sqlite3_log() containing the current value of
-** errno and, if possible, the human-readable equivalent from strerror() or
-** strerror_r().
-**
-** The first argument passed to the macro should be the error code that
-** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
-** The two subsequent arguments should be the name of the OS function that
-** failed (e.g. "unlink", "open") and the associated file-system path,
-** if any.
-*/
-#define rtthreadLogError(a,b,c) rtthreadLogErrorAtLine(a,b,c,__LINE__)
-static int rtthreadLogErrorAtLine(
- int errcode, /* SQLite error code */
- const char *zFunc, /* Name of OS function that failed */
- const char *zPath, /* File path associated with error */
- int iLine /* Source line number where error occurred */
-){
- char *zErr; /* Message from strerror() or equivalent */
- int iErrno = errno; /* Saved syscall error number */
-
- /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
- ** the strerror() function to obtain the human-readable error message
- ** equivalent to errno. Otherwise, use strerror_r().
- */
-#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R)
- char aErr[80];
- memset(aErr, 0, sizeof(aErr));
- zErr = aErr;
-
- /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
- ** assume that the system provides the GNU version of strerror_r() that
- ** returns a pointer to a buffer containing the error message. That pointer
- ** may point to aErr[], or it may point to some static storage somewhere.
- ** Otherwise, assume that the system provides the POSIX version of
- ** strerror_r(), which always writes an error message into aErr[].
- **
- ** If the code incorrectly assumes that it is the POSIX version that is
- ** available, the error message will often be an empty string. Not a
- ** huge problem. Incorrectly concluding that the GNU version is available
- ** could lead to a segfault though.
- */
-#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
- zErr =
-# endif
- strerror_r(iErrno, aErr, sizeof(aErr)-1);
-
-#elif SQLITE_THREADSAFE
- /* This is a threadsafe build, but strerror_r() is not available. */
- zErr = "";
-#else
- /* Non-threadsafe build, use strerror(). */
- zErr = strerror(iErrno);
-#endif
-
- if( zPath==0 ) zPath = "";
- sqlite3_log(errcode,
- "os_rtthread.c:%d: (%d) %s(%s) - %s",
- iLine, iErrno, zFunc, zPath, zErr
- );
-
- return errcode;
-}
-
-
-/*
-** Do not accept any file descriptor less than this value, in order to avoid
-** opening database file using file descriptors that are commonly used for
-** standard input, output, and error.
-*/
-#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
-# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3
-#endif
-
-/*
-** Invoke open(). Do so multiple times, until it either succeeds or
-** fails for some reason other than EINTR.
-**
-** If the file creation mode "m" is 0 then set it to the default for
-** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
-** 0644) as modified by the system umask. If m is not 0, then
-** make the file creation mode be exactly m ignoring the umask.
-**
-** The m parameter will be non-zero only when creating -wal, -journal,
-** and -shm files. We want those files to have *exactly* the same
-** permissions as their original database, unadulterated by the umask.
-** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
-** transaction crashes and leaves behind hot journals, then any
-** process that is able to write to the database will also be able to
-** recover the hot journals.
-*/
-static int robust_open(const char *z, int f, mode_t m){
- int fd;
- mode_t m2 = m ;
- while(1){
-#if defined(O_CLOEXEC)
- fd = osOpen(z,f|O_CLOEXEC,m2);
-#else
- fd = osOpen(z,f,m2);
-#endif
- if( fd<0 ){
- if( errno==EINTR ) continue;
- break;
- }
- if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
- osClose(fd);
- sqlite3_log(SQLITE_WARNING,
- "attempt to open \"%s\" as file descriptor %d", z, fd);
- fd = -1;
- if( osOpen("/000111sql.test111000", f, m)<0 ) break;
- }
-
- return fd;
-}
-
-/*
-** Open a file descriptor to the directory containing file zFilename.
-** If successful, *pFd is set to the opened file descriptor and
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-** value.
-**
-** The directory file descriptor is used for only one thing - to
-** fsync() a directory to make sure file creation and deletion events
-** are flushed to disk. Such fsyncs are not needed on newer
-** journaling filesystems, but are required on older filesystems.
-**
-** This routine can be overridden using the xSetSysCall interface.
-** The ability to override this routine was added in support of the
-** chromium sandbox. Opening a directory is a security risk (we are
-** told) so making it overrideable allows the chromium sandbox to
-** replace this routine with a harmless no-op. To make this routine
-** a no-op, replace it with a stub that returns SQLITE_OK but leaves
-** *pFd set to a negative number.
-**
-** If SQLITE_OK is returned, the caller is responsible for closing
-** the file descriptor *pFd using close().
-*/
-static int openDirectory(const char *zFilename, int *pFd){
- int ii;
- int fd = -1;
- char zDirname[MAX_PATHNAME+1];
-
- sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
- for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
- if( ii>0 ){
- zDirname[ii] = '\0';
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
- if( fd>=0 ){
- OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
- }
- }
- *pFd = fd;
- return (fd>=0?SQLITE_OK:rtthreadLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
-}
-
-
-
-/*
-** This is the xSetSystemCall() method of sqlite3_vfs for all of the
-** "win32" VFSes. Return SQLITE_OK opon successfully updating the
-** system call pointer, or SQLITE_NOTFOUND if there is no configurable
-** system call named zName.
-*/
-static int rtthreadSetSystemCall(
- sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */
- const char *zName, /* Name of system call to override */
- sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */
-){
- unsigned int i;
- int rc = SQLITE_NOTFOUND;
-
- UNUSED_PARAMETER(pNotUsed);
- if( zName==0 ){
- /* If no zName is given, restore all system calls to their default
- ** settings and return NULL
- */
- rc = SQLITE_OK;
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( aSyscall[i].pDefault ){
- aSyscall[i].pCurrent = aSyscall[i].pDefault;
- }
- }
- }else{
- /* If zName is specified, operate on only the one system call
- ** specified.
- */
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ){
- if( aSyscall[i].pDefault==0 ){
- aSyscall[i].pDefault = aSyscall[i].pCurrent;
- }
- rc = SQLITE_OK;
- if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
- aSyscall[i].pCurrent = pNewFunc;
- break;
- }
- }
- }
- return rc;
-}
-
-/*
-** Return the value of a system call. Return NULL if zName is not a
-** recognized system call name. NULL is also returned if the system call
-** is currently undefined.
-*/
-static sqlite3_syscall_ptr rtthreadGetSystemCall(
- sqlite3_vfs *pNotUsed,
- const char *zName
-){
- unsigned int i;
-
- UNUSED_PARAMETER(pNotUsed);
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
- }
- return 0;
-}
-
-/*
-** Return the name of the first system call after zName. If zName==NULL
-** then return the name of the first system call. Return NULL if zName
-** is the last system call or if zName is not the name of a valid
-** system call.
-*/
-static const char* rtthreadNextSystemCall(sqlite3_vfs *p, const char *zName){
- int i = -1;
-
- UNUSED_PARAMETER(p);
- if( zName ){
- for(i=0; i<ArraySize(aSyscall)-1; i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) break;
- }
- }
- for(i++; i<ArraySize(aSyscall); i++){
- if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
- }
- return 0;
-}
-
-/*
-** The following routine suspends the current thread for at least ms
-** milliseconds. This is equivalent to the Win32 Sleep() interface.
-*/
-void sqlite3_rtthread_sleep(int milliseconds){
- rt_tick_t sleep_tick;
-
- if (milliseconds <= 0)
- return;
-
- sleep_tick = rt_tick_from_millisecond(milliseconds);
-
- osSleep(sleep_tick);
-}
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the unixInodeInfo and
-** vxworksFileId objects used by this file, all of which may be
-** shared by multiple threads.
-**
-** Function unixMutexHeld() is used to assert() that the global mutex
-** is held when required. This function is only used as part of assert()
-** statements. e.g.
-**
-** unixEnterMutex()
-** assert( unixMutexHeld() );
-** unixEnterLeave()
-*/
-static void rtthreadEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void rtthreadLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int rtthreadMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#endif
-
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-/*
-** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
-** integer lock-type.
-*/
-static const char *azFileLock(int eFileLock){
- switch( eFileLock ){
- case NO_LOCK: return "NONE";
- case SHARED_LOCK: return "SHARED";
- case RESERVED_LOCK: return "RESERVED";
- case PENDING_LOCK: return "PENDING";
- case EXCLUSIVE_LOCK: return "EXCLUSIVE";
- }
- return "ERROR";
-}
-#endif
-
-/*
-** This routine translates a standard POSIX errno code into something
-** useful to the clients of the sqlite3 functions. Specifically, it is
-** intended to translate a variety of "try again" errors into SQLITE_BUSY
-** and a variety of "please close the file descriptor NOW" errors into
-** SQLITE_IOERR
-**
-** Errors during initialization of locks, or file system support for locks,
-** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-*/
-static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
- switch (posixError) {
-#if 0
- /* At one point this code was not commented out. In theory, this branch
- ** should never be hit, as this function should only be called after
- ** a locking-related function (i.e. fcntl()) has returned non-zero with
- ** the value of errno as the first argument. Since a system call has failed,
- ** errno should be non-zero.
- **
- ** Despite this, if errno really is zero, we still don't want to return
- ** SQLITE_OK. The system call failed, and *some* SQLite error should be
- ** propagated back to the caller. Commenting this branch out means errno==0
- ** will be handled by the "default:" case below.
- */
- case 0:
- return SQLITE_OK;
-#endif
-
- case DFS_STATUS_EAGAIN:
- case ETIMEDOUT:
- case DFS_STATUS_EBUSY:
- case EINTR:
- case ENOLCK:
- /* random NFS retry error, unless during file system support
- * introspection, in which it actually means what it says */
- return SQLITE_BUSY;
-
- case EACCES:
- /* EACCES is like EAGAIN during locking operations, but not any other time*/
- if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
- (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
- return SQLITE_BUSY;
- }
- /* else fall through */
- case EPERM:
- return SQLITE_PERM;
-
- /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
- ** this module never makes such a call. And the code in SQLite itself
- ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons
- ** this case is also commented out. If the system does set errno to EDEADLK,
- ** the default SQLITE_IOERR_XXX code will be returned. */
-#if 0
- case EDEADLK:
- return SQLITE_IOERR_BLOCKED;
-#endif
-
-#if EOPNOTSUPP!=ENOTSUP
- case EOPNOTSUPP:
- /* something went terribly awry, unless during file system support
- * introspection, in which it actually means what it says */
-#endif
-#ifdef ENOTSUP
- case ENOTSUP:
- /* invalid fd, unless during file system support introspection, in which
- * it actually means what it says */
-#endif
- case DFS_STATUS_EIO:
- case DFS_STATUS_EBADF:
- case DFS_STATUS_EINVAL:
- case ENOTCONN:
- case DFS_STATUS_ENODEV:
- case DFS_STATUS_ENXIO:
- case DFS_STATUS_ENOENT:
-#ifdef ESTALE /* ESTALE is not defined on Interix systems */
- case ESTALE:
-#endif
- case DFS_STATUS_ENOSYS:
- /* these should force the client to close the file and reconnect */
-
- default:
- return sqliteIOErr;
- }
-}
-
-static int robust_ftruncate(int h, sqlite3_int64 sz){
- int rc;
- rc = -1;
- return rc;
-}
-
-/*
-** Close a file descriptor.
-**
-** We assume that close() almost always works, since it is only in a
-** very sick application or on a very sick platform that it might fail.
-** If it does fail, simply leak the file descriptor, but do log the
-** error.
-**
-** Note that it is not safe to retry close() after EINTR since the
-** file descriptor might have already been reused by another thread.
-** So we don't even try to recover from an EINTR. Just log the error
-** and move on.
-*/
-static void robust_close(rtthreadFile *pFile, int h, int lineno){
- if( osClose(h) ){
- rtthreadLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
- pFile ? pFile->zPath : 0, lineno);
- }
-}
-
-/*
-** Check a rtthreadFile that is a database. Verify the following:
-**
-** (1) There is exactly one hard link on the file
-** (2) The file is not a symbolic link
-** (3) The file has not been renamed or unlinked
-**
-** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
-*/
-static void verifyDbFile(rtthreadFile *pFile){
- struct stat buf;
- int rc;
- if( pFile->ctrlFlags & UNIXFILE_WARNED ){
- /* One or more of the following warnings have already been issued. Do not
- ** repeat them so as not to clutter the error log */
- return;
- }
- rc = osFstat(pFile->h, &buf);
- if( rc!=0 ){
- sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
- pFile->ctrlFlags |= UNIXFILE_WARNED;
- return;
- }
-#warning " struct \"stat\" has no field \"st_nlink\""
-#ifndef RT_USING_SQLITE
- if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
- sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
- pFile->ctrlFlags |= UNIXFILE_WARNED;
- return;
- }
-#endif
-}
-
-/*
-** This function performs the parts of the "close file" operation
-** common to all locking schemes. It closes the directory and file
-** handles, if they are valid, and sets all fields of the rtthreadFile
-** structure to 0.
-**
-** It is *not* necessary to hold the mutex when this routine is called,
-** even on VxWorks. A mutex will be acquired on VxWorks by the
-** vxworksReleaseFileId() routine.
-*/
-static int closeRtthreadFile(sqlite3_file *id){
- rtthreadFile *pFile = (rtthreadFile*)id;
- if( pFile->h>=0 ){
- robust_close(pFile, pFile->h, __LINE__);
- pFile->h = -1;
- }
- OSTRACE(("CLOSE %-3d\n", pFile->h));
- OpenCounter(-1);
- memset(pFile, 0, sizeof(rtthreadFile));
- return SQLITE_OK;
-}
-
-/************** End of the posix advisory lock implementation *****************
-******************************************************************************/
-
-/******************************************************************************
-****************************** No-op Locking **********************************
-**
-** Of the various locking implementations available, this is by far the
-** simplest: locking is ignored. No attempt is made to lock the database
-** file for reading or writing.
-**
-** This locking mode is appropriate for use on read-only databases
-** (ex: databases that are burned into CD-ROM, for example.) It can
-** also be used if the application employs some external mechanism to
-** prevent simultaneous access of the same database by two or more
-** database connections. But there is a serious risk of database
-** corruption if this locking mode is used in situations where multiple
-** database connections are accessing the same database file at the same
-** time and one or more of those connections are writing.
-*/
-
-static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
- UNUSED_PARAMETER(NotUsed);
- *pResOut = 0;
- return SQLITE_OK;
-}
-static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-static int nolockClose(sqlite3_file *id) {
- return closeRtthreadFile(id);
-}
-
-/******************* End of the no-op lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-************************* Begin dot-file Locking ******************************
-**
-** The dotfile locking implementation uses the existence of separate lock
-** files (really a directory) to control access to the database. This works
-** on just about every filesystem imaginable. But there are serious downsides:
-**
-** (1) There is zero concurrency. A single reader blocks all other
-** connections from reading or writing the database.
-**
-** (2) An application crash or power loss can leave stale lock files
-** sitting around that need to be cleared manually.
-**
-** Nevertheless, a dotlock is an appropriate locking mode for use if no
-** other locking strategy is available.
-**
-** Dotfile locking works by creating a subdirectory in the same directory as
-** the database and with the same name but with a ".lock" extension added.
-** The existence of a lock directory implies an EXCLUSIVE lock. All other
-** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
-*/
-
-/*
-** The file suffix added to the data base filename in order to create the
-** lock directory.
-*/
-#define DOTLOCK_SUFFIX ".lock"
-
-/*
-** Only set the lastErrno if the error code is a real error and not
-** a normal expected return code of SQLITE_BUSY or SQLITE_OK
-*/
-#define IS_LOCK_ERROR(x) (((x) != SQLITE_OK) && ((x) != SQLITE_BUSY))
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-**
-** In dotfile locking, either a lock exists or it does not. So in this
-** variation of CheckReservedLock(), *pResOut is set to true if any lock
-** is held on the file and false if the file is unlocked.
-*/
-static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
- rtthreadFile *pFile = (rtthreadFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- /* Either this connection or some other connection in the same process
- ** holds a lock on the file. No need to check further. */
- reserved = 1;
- }else{
- /* The lock is held if and only if the lockfile exists */
- const char *zLockFile = (const char*)pFile->lockingContext;
- reserved = 0;
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-**
-** With dotfile locking, we really only support state (4): EXCLUSIVE.
-** But we track the other locking levels internally.
-*/
-static int dotlockLock(sqlite3_file *id, int eFileLock) {
- rtthreadFile *pFile = (rtthreadFile*)id;
- char *zLockFile = (char *)pFile->lockingContext;
- int rc = SQLITE_OK;
-
-
- /* If we have any lock, then the lock file already exists. All we have
- ** to do is adjust our internal record of the lock level.
- */
- if( pFile->eFileLock > NO_LOCK ){
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
- rc = osMkdir(zLockFile, 0777);
- if( rc<0 ){
- /* failed to open/create the lock directory */
- int tErrno = errno;
- if( DFS_STATUS_EEXIST == tErrno ){
- rc = SQLITE_BUSY;
- } else {
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- }
- return rc;
- }
-
- /* got it, set the type and return ok */
- pFile->eFileLock = eFileLock;
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** When the locking level reaches NO_LOCK, delete the lock file.
-*/
-static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
- rtthreadFile *pFile = (rtthreadFile*)id;
- char *zLockFile = (char *)pFile->lockingContext;
- int rc;
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d tnm=%s (dotlock)\n", pFile->h, eFileLock,
- pFile->eFileLock, rt_thread_self()->name ));
- assert( eFileLock<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->eFileLock==eFileLock ){
- return SQLITE_OK;
- }
-
- /* To downgrade to shared, simply update our internal notion of the
- ** lock state. No need to mess with the file on disk.
- */
- if( eFileLock==SHARED_LOCK ){
- pFile->eFileLock = SHARED_LOCK;
- return SQLITE_OK;
- }
-
- /* To fully unlock the database, delete the lock file */
- assert( eFileLock==NO_LOCK );
- rc = osRmdir(zLockFile);
- if( rc<0 && errno==DFS_STATUS_ENOTDIR ) rc = osUnlink(zLockFile);
- if( rc<0 ){
- int tErrno = errno;
- rc = 0;
- if( DFS_STATUS_ENOENT != tErrno ){
- rc = SQLITE_IOERR_UNLOCK;
- }
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- }
- pFile->eFileLock = NO_LOCK;
- return SQLITE_OK;
-}
-
-/*
-** Close a file. Make sure the lock has been released before closing.
-*/
-static int dotlockClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- rtthreadFile *pFile = (rtthreadFile*)id;
- dotlockUnlock(id, NO_LOCK);
- sqlite3_free(pFile->lockingContext);
- rc = closeRtthreadFile(id);
- }
- return rc;
-}
-/****************** End of the dot-file lock implementation *******************
-******************************************************************************/
-
-/******************************************************************************
-************************** Begin flock Locking ********************************
-**
-** Use the flock() system call to do file locking.
-**
-** flock() locking is like dot-file locking in that the various
-** fine-grain locking levels supported by SQLite are collapsed into
-** a single exclusive lock. In other words, SHARED, RESERVED, and
-** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite
-** still works when you do this, but concurrency is reduced since
-** only a single process can be reading the database at a time.
-**
-** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
-** compiling for VXWORKS.
-*/
-#if SQLITE_ENABLE_LOCKING_STYLE
-#warning "rtthread file lock not available"
-/*
-** Retry flock() calls that fail with EINTR
-*/
-static int robust_flock(int fd, int op){
- int rc = 0;
-
- return rc;
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- rtthreadFile *pFile = (rtthreadFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- /* attempt to get the lock */
- int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
- if( !lrc ){
- /* got the lock, unlock it */
- lrc = robust_flock(pFile->h, LOCK_UN);
- if ( lrc ) {
- int tErrno = errno;
- /* unlock failed with an error */
- lrc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- } else {
- int tErrno = errno;
- reserved = 1;
- /* someone else might have it reserved */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
-
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_OK;
- reserved=1;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** flock() only really support EXCLUSIVE locks. We track intermediate
-** lock states in the sqlite3_file structure, but all locks SHARED or
-** above are really EXCLUSIVE locks and exclude all other processes from
-** access the file.
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int flockLock(sqlite3_file *id, int eFileLock) {
- int rc = SQLITE_OK;
- rtthreadFile *pFile = (rtthreadFile*)id;
-
- assert( pFile );
-
- /* if we already have a lock, it is exclusive.
- ** Just adjust level and punt on outta here. */
- if (pFile->eFileLock > NO_LOCK) {
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
-
- if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) {
- int tErrno = errno;
- /* didn't get, must be busy */
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- } else {
- /* got it, set the type and return ok */
- pFile->eFileLock = eFileLock;
- }
- OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock),
- rc==SQLITE_OK ? "ok" : "failed"));
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_BUSY;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- return rc;
-}
-
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int flockUnlock(sqlite3_file *id, int eFileLock) {
- rtthreadFile *pFile = (rtthreadFile*)id;
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d tnm=%s (flock)\n", pFile->h, eFileLock,
- pFile->eFileLock, rt_thread_self()->name));
- assert( eFileLock<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->eFileLock==eFileLock ){
- return SQLITE_OK;
- }
-
- /* shared can just be set because we always have an exclusive */
- if (eFileLock==SHARED_LOCK) {
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* no, really, unlock. */
- if( robust_flock(pFile->h, LOCK_UN) ){
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- return SQLITE_OK;
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- return SQLITE_IOERR_UNLOCK;
- }else{
- pFile->eFileLock = NO_LOCK;
- return SQLITE_OK;
- }
-}
-
-/*
-** Close a file.
-*/
-static int flockClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- flockUnlock(id, NO_LOCK);
- rc = closeRtthreadFile(id);
- }
- return rc;
-}
-
-#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
-
-/******************* End of the flock lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-**************** Non-locking sqlite3_file methods *****************************
-**
-** The next division contains implementations for all methods of the
-** sqlite3_file object other than the locking methods. The locking
-** methods were defined in divisions above (one locking method per
-** division). Those methods that are common to all locking modes
-** are gather together into this division.
-*/
-
-/*
-** Seek to the offset passed as the second argument, then read cnt
-** bytes into pBuf. Return the number of bytes actually read.
-**
-** NB: If you define USE_PREAD or USE_PREAD64, then it might also
-** be necessary to define _XOPEN_SOURCE to be 500. This varies from
-** one system to another. Since SQLite does not define USE_PREAD
-** any any form by default, we will not attempt to define _XOPEN_SOURCE.
-** See tickets #2741 and #2681.
-**
-** To avoid stomping the errno value on a failed read the lastErrno value
-** is set before returning.
-*/
-static int seekAndRead(rtthreadFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
- int got;
- int prior = 0;
-#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
- i64 newOffset;
-#endif
- TIMER_START;
- assert( cnt==(cnt&0x1ffff) );
- assert( id->h>2 );
- cnt &= 0x1ffff;
- do{
-#if defined(USE_PREAD)
- #error "rtthread pread not support"
- got = osPread(id->h, pBuf, cnt, offset);
- SimulateIOError( got = -1 );
-#elif defined(USE_PREAD64)
- #error "rtthread pread64 not support"
- got = osPread64(id->h, pBuf, cnt, offset);
- SimulateIOError( got = -1 );
-#else
- newOffset = lseek(id->h, offset, SEEK_SET);
- SimulateIOError( newOffset-- );
- if( newOffset!=offset ){
- if( newOffset == -1 ){
- ((rtthreadFile*)id)->lastErrno = errno;
- }else{
- ((rtthreadFile*)id)->lastErrno = 0;
- }
- return -1;
- }
- got = osRead(id->h, pBuf, cnt);
-#endif
- if( got==cnt ) break;
- if( got<0 ){
- if( errno==EINTR ){ got = 1; continue; }
- prior = 0;
- ((rtthreadFile*)id)->lastErrno = errno;
- break;
- }else if( got>0 ){
- cnt -= got;
- offset += got;
- prior += got;
- pBuf = (void*)(got + (char*)pBuf);
- }
- }while( got>0 );
- TIMER_END;
- OSTRACE(("READ %-3d %5d %7lld %llu\n",
- id->h, got+prior, offset-prior, TIMER_ELAPSED));
- return got+prior;
-}
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int rtthreadRead(
- sqlite3_file *id,
- void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- rtthreadFile *pFile = (rtthreadFile *)id;
- int got;
- assert( id );
- assert( offset>=0 );
- assert( amt>0 );
-
- got = seekAndRead(pFile, offset, pBuf, amt);
- if( got==amt ){
- return SQLITE_OK;
- }else if( got<0 ){
- /* lastErrno set by seekAndRead */
- return SQLITE_IOERR_READ;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- /* Unread parts of the buffer must be zero-filled */
- memset(&((char*)pBuf)[got], 0, amt-got);
- return SQLITE_IOERR_SHORT_READ;
- }
-}
-
-/*
-** Attempt to seek the file-descriptor passed as the first argument to
-** absolute offset iOff, then attempt to write nBuf bytes of data from
-** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise,
-** return the actual number of bytes written (which may be less than
-** nBuf).
-*/
-static int seekAndWriteFd(
- int fd, /* File descriptor to write to */
- i64 iOff, /* File offset to begin writing at */
- const void *pBuf, /* Copy data from this buffer to the file */
- int nBuf, /* Size of buffer pBuf in bytes */
- int *piErrno /* OUT: Error number if error occurs */
-){
- int rc = 0; /* Value returned by system call */
-
- assert( nBuf==(nBuf&0x1ffff) );
- assert( fd>2 );
- nBuf &= 0x1ffff;
- TIMER_START;
-
-#if defined(USE_PREAD)
- do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
-#elif defined(USE_PREAD64)
- do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
-#else
- do{
- i64 iSeek = lseek(fd, iOff, SEEK_SET);
- SimulateIOError( iSeek-- );
-
- if( iSeek!=iOff ){
- if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
- return -1;
- }
- rc = osWrite(fd, pBuf, nBuf);
- }while( rc<0 && errno==EINTR );
-#endif
-
- TIMER_END;
- OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
-
- if( rc<0 && piErrno ) *piErrno = errno;
- return rc;
-}
-
-
-/*
-** Seek to the offset in id->offset then read cnt bytes into pBuf.
-** Return the number of bytes actually read. Update the offset.
-**
-** To avoid stomping the errno value on a failed write the lastErrno value
-** is set before returning.
-*/
-static int seekAndWrite(rtthreadFile *id, i64 offset, const void *pBuf, int cnt){
- return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno);
-}
-
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int rtthreadWrite(
- sqlite3_file *id,
- const void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- rtthreadFile *pFile = (rtthreadFile*)id;
- int wrote = 0;
- assert( id );
- assert( amt>0 );
-
-#ifdef SQLITE_DEBUG
- /* If we are doing a normal write to a database file (as opposed to
- ** doing a hot-journal rollback or a write to some file other than a
- ** normal database file) then record the fact that the database
- ** has changed. If the transaction counter is modified, record that
- ** fact too.
- */
- if( pFile->inNormalWrite ){
- pFile->dbUpdate = 1; /* The database has been modified */
- if( offset<=24 && offset+amt>=27 ){
- int rc;
- char oldCntr[4];
- SimulateIOErrorBenign(1);
- rc = seekAndRead(pFile, 24, oldCntr, 4);
- SimulateIOErrorBenign(0);
- if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
- pFile->transCntrChng = 1; /* The transaction counter has changed */
- }
- }
- }
-#endif
-
- while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
- amt -= wrote;
- offset += wrote;
- pBuf = &((char*)pBuf)[wrote];
- }
- SimulateIOError(( wrote=(-1), amt=1 ));
- SimulateDiskfullError(( wrote=0, amt=1 ));
-
- if( amt>0 ){
- if( wrote<0 && pFile->lastErrno!=DFS_STATUS_ENOSPC ){
- /* lastErrno set by seekAndWrite */
- return SQLITE_IOERR_WRITE;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- return SQLITE_FULL;
- }
- }
-
- return SQLITE_OK;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occurring at the right times.
-*/
-int sqlite3_sync_count = 0;
-int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** We do not trust systems to provide a working fdatasync(). Some do.
-** Others do no. To be safe, we will stick with the (slightly slower)
-** fsync(). If you know that your system does support fdatasync() correctly,
-** then simply compile with -Dfdatasync=fdatasync
-*/
-#if !defined(fdatasync)
-#include "dfs.h"
-#include "dfs_file.h"
-int fdatasync(fd)
-{
- struct dfs_fd *dfs_fd;
- dfs_fd = fd_get(fd);
- return dfs_file_flush(dfs_fd);
-}
-#endif
-
-/*
-** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
-** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently
-** only available on Mac OS X. But that could change.
-*/
-#ifdef F_FULLFSYNC
-# define HAVE_FULLFSYNC 0
-#endif
-
-
-/*
-** The fsync() system call does not work as advertised on many
-** unix systems. The following procedure is an attempt to make
-** it work better.
-**
-** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful
-** for testing when we want to run through the test suite quickly.
-** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
-** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
-** or power failure will likely corrupt the database file.
-**
-** SQLite sets the dataOnly flag if the size of the file is unchanged.
-** The idea behind dataOnly is that it should only write the file content
-** to disk, not the inode. We only set dataOnly if the file size is
-** unchanged since the file size is part of the inode. However,
-** Ted Ts'o tells us that fdatasync() will also write the inode if the
-** file size has changed. The only real difference between fdatasync()
-** and fsync(), Ted tells us, is that fdatasync() will not flush the
-** inode if the mtime or owner or other inode attributes have changed.
-** We only care about the file size, not the other file attributes, so
-** as far as SQLite is concerned, an fdatasync() is always adequate.
-** So, we always use fdatasync() if it is available, regardless of
-** the value of the dataOnly flag.
-*/
-static int full_fsync(int fd, int fullSync, int dataOnly){
- int rc;
-
- /* The following "ifdef/elif/else/" block has the same structure as
- ** the one below. It is replicated here solely to avoid cluttering
- ** up the real code with the UNUSED_PARAMETER() macros.
- */
-#ifdef SQLITE_NO_SYNC
- UNUSED_PARAMETER(fd);
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#elif HAVE_FULLFSYNC
- UNUSED_PARAMETER(dataOnly);
-#else
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#endif
-
- /* Record the number of times that we do a normal fsync() and
- ** FULLSYNC. This is used during testing to verify that this procedure
- ** gets called with the correct arguments.
- */
-#ifdef SQLITE_TEST
- if( fullSync ) sqlite3_fullsync_count++;
- sqlite3_sync_count++;
-#endif
-
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- rc = SQLITE_OK;
-#elif HAVE_FULLFSYNC
- #error "rtthread not support FULLFSYNC"
-#else
- rc = fdatasync(fd);
-#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
-
- return rc;
-}
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-**
-** If dataOnly==0 then both the file itself and its metadata (file
-** size, access time, etc) are synced. If dataOnly!=0 then only the
-** file data is synced.
-**
-** Under Rtthread, also make sure that the directory entry for the file
-** has been created by fsync-ing the directory that contains the file.
-** If we do not do this and we encounter a power failure, the directory
-** entry for the journal might not exist after we reboot. The next
-** SQLite to access the file will not know that the journal exists (because
-** the directory entry for the journal was never created) and the transaction
-** will not roll back - possibly leading to database corruption.
-*/
-static int rtthreadSync(sqlite3_file *id, int flags){
- int rc;
- rtthreadFile *pFile = (rtthreadFile*)id;
-
- int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
- int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
-
- /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
- assert((flags&0x0F)==SQLITE_SYNC_NORMAL
- || (flags&0x0F)==SQLITE_SYNC_FULL
- );
-
- /* Rtthread cannot, but some systems may return SQLITE_FULL from here. This
- ** line is to test that doing so does not cause any problems.
- */
- SimulateDiskfullError( return SQLITE_FULL );
-
- assert( pFile );
- OSTRACE(("SYNC %-3d\n", pFile->h));
- rc = full_fsync(pFile->h, isFullsync, isDataOnly);
- SimulateIOError( rc=1 );
- if( rc ){
- pFile->lastErrno = errno;
- return rtthreadLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
- }
-
- /* Also fsync the directory containing the file if the DIRSYNC flag
- ** is set. This is a one-time occurrence. Many systems (examples: AIX)
- ** are unable to fsync a directory, so ignore errors on the fsync.
- */
- if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
- int dirfd;
- OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
- HAVE_FULLFSYNC, isFullsync));
- rc = osOpenDirectory(pFile->zPath, &dirfd);
- if( rc==SQLITE_OK && dirfd>=0 ){
- full_fsync(dirfd, 0, 0);
- robust_close(pFile, dirfd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
- rc = SQLITE_OK;
- }
- pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
- }
- return rc;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int rtthreadTruncate(sqlite3_file *id, i64 nByte){
- rtthreadFile *pFile = (rtthreadFile *)id;
- int rc;
- assert( pFile );
- SimulateIOError( return SQLITE_IOERR_TRUNCATE );
-
- /* If the user has configured a chunk-size for this file, truncate the
- ** file so that it consists of an integer number of chunks (i.e. the
- ** actual file size after the operation may be larger than the requested
- ** size).
- */
- if( pFile->szChunk>0 ){
- nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
- }
-
- rc = robust_ftruncate(pFile->h, (off_t)nByte);
- if( rc ){
- pFile->lastErrno = errno;
- return rtthreadLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
- }else{
-#ifdef SQLITE_DEBUG
- /* If we are doing a normal write to a database file (as opposed to
- ** doing a hot-journal rollback or a write to some file other than a
- ** normal database file) and we truncate the file to zero length,
- ** that effectively updates the change counter. This might happen
- ** when restoring a database using the backup API from a zero-length
- ** source.
- */
- if( pFile->inNormalWrite && nByte==0 ){
- pFile->transCntrChng = 1;
- }
-#endif
-
- return SQLITE_OK;
- }
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int rtthreadFileSize(sqlite3_file *id, i64 *pSize){
- int rc;
- struct stat buf;
- assert( id );
- rc = osFstat(((rtthreadFile*)id)->h, &buf);
- SimulateIOError( rc=1 );
- if( rc!=0 ){
- ((rtthreadFile*)id)->lastErrno = errno;
- return SQLITE_IOERR_FSTAT;
- }
- *pSize = buf.st_size;
-
- /* When opening a zero-size database, the findInodeInfo() procedure
- ** writes a single byte into that file in order to work around a bug
- ** in the OS-X msdos filesystem. In order to avoid problems with upper
- ** layers, we need to report this file size as zero even though it is
- ** really 1. Ticket #3260.
- */
- if( *pSize==1 ) *pSize = 0;
-
-
- return SQLITE_OK;
-}
-
-/*
-** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
-** file-control operation. Enlarge the database to nBytes in size
-** (rounded up to the next chunk-size). If the database is already
-** nBytes or larger, this routine is a no-op.
-*/
-static int fcntlSizeHint(rtthreadFile *pFile, i64 nByte){
- if( pFile->szChunk>0 ){
- i64 nSize; /* Required file size */
- struct stat buf; /* Used to hold return values of fstat() */
-
- if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
-
- nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
- if( nSize>(i64)buf.st_size ){
- /* If the OS does not have posix_fallocate(), fake it. First use
- ** ftruncate() to set the file size, then write a single byte to
- ** the last byte in each block within the extended region. This
- ** is the same technique used by glibc to implement posix_fallocate()
- ** on systems that do not have a real fallocate() system call.
- */
- int nBlk = 4096; // no blksize in RT-Thread, use 4096. /* File-system block size */
- i64 iWrite; /* Next offset to write to */
-
- if( robust_ftruncate(pFile->h, nSize) ){
- pFile->lastErrno = errno;
- return rtthreadLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
- }
- iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
- while( iWrite<nSize ){
- int nWrite = seekAndWrite(pFile, iWrite, "", 1);
- if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
- iWrite += nBlk;
- }
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** If *pArg is inititially negative then this is a query. Set *pArg to
-** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
-**
-** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-*/
-static void rtthreadModeBit(rtthreadFile *pFile, unsigned char mask, int *pArg){
- if( *pArg<0 ){
- *pArg = (pFile->ctrlFlags & mask)!=0;
- }else if( (*pArg)==0 ){
- pFile->ctrlFlags &= ~mask;
- }else{
- pFile->ctrlFlags |= mask;
- }
-}
-
-/* Forward declaration */
-static int rtthreadGetTempname(int nBuf, char *zBuf);
-
-/*
-** Information and control of an open file handle.
-*/
-static int rtthreadFileControl(sqlite3_file *id, int op, void *pArg){
- rtthreadFile *pFile = (rtthreadFile*)id;
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = pFile->eFileLock;
- return SQLITE_OK;
- }
- case SQLITE_LAST_ERRNO: {
- *(int*)pArg = pFile->lastErrno;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_CHUNK_SIZE: {
- pFile->szChunk = *(int *)pArg;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_SIZE_HINT: {
- int rc;
- SimulateIOErrorBenign(1);
- rc = fcntlSizeHint(pFile, *(i64 *)pArg);
- SimulateIOErrorBenign(0);
- return rc;
- }
- case SQLITE_FCNTL_PERSIST_WAL: {
- rtthreadModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
- rtthreadModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
- if( zTFile ){
- rtthreadGetTempname(pFile->pVfs->mxPathname, zTFile);
- *(char**)pArg = zTFile;
- }
- return SQLITE_OK;
- }
-#ifdef SQLITE_DEBUG
- /* The pager calls this method to signal that it has done
- ** a rollback and that the database is therefore unchanged and
- ** it hence it is OK for the transaction change counter to be
- ** unchanged.
- */
- case SQLITE_FCNTL_DB_UNCHANGED: {
- ((rtthreadFile*)id)->dbUpdate = 0;
- return SQLITE_OK;
- }
-#endif
- }
- return SQLITE_NOTFOUND;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-static int rtthreadSectorSize(sqlite3_file *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-
-
-/*
-** Return the device characteristics for the file.
-**
-** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
-** However, that choice is contraversial since technically the underlying
-** file system does not always provide powersafe overwrites. (In other
-** words, after a power-loss event, parts of the file that were never
-** written might end up being altered.) However, non-PSOW behavior is very,
-** very rare. And asserting PSOW makes a large reduction in the amount
-** of required I/O for journaling, since a lot of padding is eliminated.
-** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
-** available to turn it off and URI query parameter available to turn it off.
-*/
-static int rtthreadDeviceCharacteristics(sqlite3_file *id){
- rtthreadFile *p = (rtthreadFile*)id;
- int rc = 0;
-
- if( p->ctrlFlags & UNIXFILE_PSOW ){
- rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
- }
- return rc;
-}
-
-#ifndef SQLITE_OMIT_WAL
-# error "WAL mode requires not support from the rt-thread, compile\
- with SQLITE_OMIT_WAL."
-#else
-# define rtthreadShmMap 0
-# define rtthreadShmLock 0
-# define rtthreadShmBarrier 0
-# define rtthreadShmUnmap 0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-#if SQLITE_MAX_MMAP_SIZE>0
-#error "rtthread not spportt mmap"
-#endif /* SQLITE_MAX_MMAP_SIZE>0 */
-
-/*
-** If possible, return a pointer to a mapping of file fd starting at offset
-** iOff. The mapping must be valid for at least nAmt bytes.
-**
-** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
-** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
-** Finally, if an error does occur, return an SQLite error code. The final
-** value of *pp is undefined in this case.
-**
-** If this function does return a pointer, the caller must eventually
-** release the reference by calling unixUnfetch().
-*/
-static int rtthreadFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
-
- *pp = 0;
-
- return SQLITE_OK;
-}
-
-/*
-** If the third argument is non-NULL, then this function releases a
-** reference obtained by an earlier call to unixFetch(). The second
-** argument passed to this function must be the same as the corresponding
-** argument that was passed to the unixFetch() invocation.
-**
-** Or, if the third argument is NULL, then this function is being called
-** to inform the VFS layer that, according to POSIX, any existing mapping
-** may now be invalid and should be unmapped.
-*/
-static int rtthreadUnfetch(sqlite3_file *fd, i64 iOff, void *p){
- rtthreadFile *pFd = (rtthreadFile *)fd; /* The underlying database file */
- UNUSED_PARAMETER(iOff);
-
- return SQLITE_OK;
-}
-
-/*
-** Here ends the implementation of all sqlite3_file methods.
-**
-********************** End sqlite3_file Methods *******************************
-******************************************************************************/
-
-/*
-** This division contains definitions of sqlite3_io_methods objects that
-** implement various file locking strategies. It also contains definitions
-** of "finder" functions. A finder-function is used to locate the appropriate
-** sqlite3_io_methods object for a particular database file. The pAppData
-** field of the sqlite3_vfs VFS objects are initialized to be pointers to
-** the correct finder-function for that VFS.
-**
-** Most finder functions return a pointer to a fixed sqlite3_io_methods
-** object. The only interesting finder-function is autolockIoFinder, which
-** looks at the filesystem type and tries to guess the best locking
-** strategy from that.
-**
-** For finder-funtion F, two objects are created:
-**
-** (1) The real finder-function named "FImpt()".
-**
-** (2) A constant pointer to this function named just "F".
-**
-**
-** A pointer to the F pointer is used as the pAppData value for VFS
-** objects. We have to do this instead of letting pAppData point
-** directly at the finder-function since C90 rules prevent a void*
-** from be cast into a function pointer.
-**
-**
-** Each instance of this macro generates two objects:
-**
-** * A constant sqlite3_io_methods object call METHOD that has locking
-** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
-**
-** * An I/O method finder function called FINDER that returns a pointer
-** to the METHOD object in the previous bullet.
-*/
-#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \
-static const sqlite3_io_methods METHOD = { \
- VERSION, /* iVersion */ \
- CLOSE, /* xClose */ \
- rtthreadRead, /* xRead */ \
- rtthreadWrite, /* xWrite */ \
- rtthreadTruncate, /* xTruncate */ \
- rtthreadSync, /* xSync */ \
- rtthreadFileSize, /* xFileSize */ \
- LOCK, /* xLock */ \
- UNLOCK, /* xUnlock */ \
- CKLOCK, /* xCheckReservedLock */ \
- rtthreadFileControl, /* xFileControl */ \
- rtthreadSectorSize, /* xSectorSize */ \
- rtthreadDeviceCharacteristics, /* xDeviceCapabilities */ \
- rtthreadShmMap, /* xShmMap */ \
- rtthreadShmLock, /* xShmLock */ \
- rtthreadShmBarrier, /* xShmBarrier */ \
- rtthreadShmUnmap, /* xShmUnmap */ \
- rtthreadFetch, /* xFetch */ \
- rtthreadUnfetch, /* xUnfetch */ \
-}; \
-static const sqlite3_io_methods *FINDER##Impl(const char *z, rtthreadFile *p){ \
- UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
- return &METHOD; \
-} \
-static const sqlite3_io_methods *(*const FINDER)(const char*,rtthreadFile *p) \
- = FINDER##Impl;
-
-/*
-** Here are all of the sqlite3_io_methods objects for each of the
-** locking strategies. Functions that return pointers to these methods
-** are also created.
-*/
-IOMETHODS(
- nolockIoFinder, /* Finder function name */
- nolockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- nolockClose, /* xClose method */
- nolockLock, /* xLock method */
- nolockUnlock, /* xUnlock method */
- nolockCheckReservedLock /* xCheckReservedLock method */
-)
-IOMETHODS(
- dotlockIoFinder, /* Finder function name */
- dotlockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- dotlockClose, /* xClose method */
- dotlockLock, /* xLock method */
- dotlockUnlock, /* xUnlock method */
- dotlockCheckReservedLock /* xCheckReservedLock method */
-)
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-IOMETHODS(
- flockIoFinder, /* Finder function name */
- flockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- flockClose, /* xClose method */
- flockLock, /* xLock method */
- flockUnlock, /* xUnlock method */
- flockCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-/*
-** An abstract type for a pointer to a IO method finder function:
-*/
-typedef const sqlite3_io_methods *(*finder_type)(const char*,rtthreadFile*);
-
-
-/****************************************************************************
-**************************** sqlite3_vfs methods ****************************
-**
-** This division contains the implementation of methods on the
-** sqlite3_vfs object.
-*/
-
-/*
-** Initialize the contents of the rtthreadFile structure pointed to by pId.
-*/
-static int fillInRtthreadFile(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- int h, /* Open file descriptor of file being opened */
- sqlite3_file *pId, /* Write to the rtthreadFile structure here */
- const char *zFilename, /* Name of the file being opened */
- int ctrlFlags /* Zero or more UNIXFILE_* values */
-){
- const sqlite3_io_methods *pLockingStyle;
- rtthreadFile *pNew = (rtthreadFile *)pId;
- int rc = SQLITE_OK;
-
- assert( pNew->pInode==NULL );
-
- /* Usually the path zFilename should not be a relative pathname. The
- ** exception is when opening the proxy "conch" file in builds that
- ** include the special Apple locking styles.
- */
- assert( zFilename==0 || zFilename[0]=='/' );
-
- /* No locking occurs in temporary files */
- assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
-
- OSTRACE(("OPEN %-3d %s\n", h, zFilename));
- pNew->h = h;
- pNew->pVfs = pVfs;
- pNew->zPath = zFilename;
- pNew->ctrlFlags = (u8)ctrlFlags;
- if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
- "psow", SQLITE_POWERSAFE_OVERWRITE) ){
- pNew->ctrlFlags |= UNIXFILE_PSOW;
- }
- if( strcmp(pVfs->zName,"unix-excl")==0 ){
- pNew->ctrlFlags |= UNIXFILE_EXCL;
- }
-
- if( ctrlFlags & UNIXFILE_NOLOCK ){
- pLockingStyle = &nolockIoMethods;
- }else{
- pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
-#if SQLITE_ENABLE_LOCKING_STYLE
- /* Cache zFilename in the locking context (AFP and dotlock override) for
- ** proxyLock activation is possible (remote proxy is based on db name)
- ** zFilename remains valid until file is closed, to support */
- pNew->lockingContext = (void*)zFilename;
-#endif
- }
-
- if( pLockingStyle == &dotlockIoMethods ){
- /* Dotfile locking uses the file path so it needs to be included in
- ** the dotlockLockingContext
- */
- char *zLockFile;
- int nFilename;
- assert( zFilename!=0 );
- nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc(nFilename);
- if( zLockFile==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
- }
- pNew->lockingContext = zLockFile;
- }
-
- pNew->lastErrno = 0;
- if( rc!=SQLITE_OK ){
- if( h>=0 ) robust_close(pNew, h, __LINE__);
- }else{
- pNew->pMethod = pLockingStyle;
- OpenCounter(+1);
- verifyDbFile(pNew);
- }
- return rc;
-}
-
-/*
-** 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* rtthreadTempFileDir(void){
- static const char *azDirs[] = {
- 0,
- "/sql",
- "/sql/tmp"
- "/tmp",
- 0 /* List terminator */
- };
- unsigned int i;
- struct stat buf;
- const char *zDir = 0;
-
- azDirs[0] = sqlite3_temp_directory;
-
- for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
- if( zDir==0 ) continue;
- if( osStat(zDir, &buf) ) continue;
- if( !S_ISDIR(buf.st_mode) ) 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 rtthreadGetTempname(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 = rtthreadTempFileDir();
- 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) + 18) >= (size_t)nBuf ){
- return SQLITE_ERROR;
- }
-
- do{
- sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
- j = (int)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;
- zBuf[j+1] = 0;
- }while( osAccess(zBuf,0)==0 );
- return SQLITE_OK;
-}
-
-/*
-** Open the file zPath.
-**
-** Previously, the SQLite OS layer used three functions in place of this
-** one:
-**
-** sqlite3OsOpenReadWrite();
-** sqlite3OsOpenReadOnly();
-** sqlite3OsOpenExclusive();
-**
-** These calls correspond to the following combinations of flags:
-**
-** ReadWrite() -> (READWRITE | CREATE)
-** ReadOnly() -> (READONLY)
-** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
-**
-** The old OpenExclusive() accepted a boolean argument - "delFlag". If
-** true, the file was configured to be automatically deleted when the
-** file handle closed. To achieve the same effect using this new
-** interface, add the DELETEONCLOSE flag to those specified above for
-** OpenExclusive().
-*/
-static int rtthreadOpen(
- sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */
- const char *zPath, /* Pathname of file to be opened */
- sqlite3_file *pFile, /* The file descriptor to be filled in */
- int flags, /* Input flags to control the opening */
- int *pOutFlags /* Output flags returned to SQLite core */
-){
- rtthreadFile *p = (rtthreadFile *)pFile;
- int fd = -1; /* File descriptor returned by open() */
- int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
- int noLock; /* True to omit locking primitives */
- int rc = SQLITE_OK; /* Function Return Code */
- int ctrlFlags = 0; /* UNIXFILE_* flags */
-
- int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
- int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
- int isCreate = (flags & SQLITE_OPEN_CREATE);
- int isReadonly = (flags & SQLITE_OPEN_READONLY);
- int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
-#if SQLITE_ENABLE_LOCKING_STYLE
- int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY);
-#endif
-
- /* If creating a master or main-file journal, this function will open
- ** a file-descriptor on the directory too. The first time unixSync()
- ** is called the directory file descriptor will be fsync()ed and close()d.
- */
- int syncDir = (isCreate && (
- eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_MAIN_JOURNAL
- || eType==SQLITE_OPEN_WAL
- ));
-
- /* 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+2];
- const char *zName = zPath;
-
- /* Check the following statements are true:
- **
- ** (a) Exactly one of the READWRITE and READONLY flags must be set, and
- ** (b) if CREATE is set, then READWRITE must also be set, and
- ** (c) if EXCLUSIVE is set, then CREATE must also be set.
- ** (d) if DELETEONCLOSE is set, then CREATE must also be set.
- */
- assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
- assert(isCreate==0 || isReadWrite);
- assert(isExclusive==0 || isCreate);
- assert(isDelete==0 || isCreate);
-
- /* The main DB, main journal, WAL file and master journal are never
- ** automatically deleted. Nor are they ever temporary files. */
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-
- /* Assert that the upper layer has set one of the "file-type" flags. */
- assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
- || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
- || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
- );
-
- memset(p, 0, sizeof(rtthreadFile));
- if( !zName ){
- /* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !syncDir);
- rc = rtthreadGetTempname(MAX_PATHNAME+2, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zName = zTmpname;
-
- /* Generated temporary filenames are always double-zero terminated
- ** for use by sqlite3_uri_parameter(). */
- assert( zName[strlen(zName)+1]==0 );
- }
-
- /* Determine the value of the flags parameter passed to POSIX function
- ** open(). These must be calculated even if open() is not called, as
- ** they may be stored as part of the file handle and used by the
- ** 'conch file' locking functions later on. */
- if( isReadonly ) openFlags |= O_RDONLY;
- if( isReadWrite ) openFlags |= O_RDWR;
- if( isCreate ) openFlags |= O_CREAT;
- if( isExclusive ) openFlags |= (O_EXCL|0/*O_NOFOLLOW8*/);
- openFlags |= (0/*O_LARGEFILE*/|O_BINARY);
-
- if( fd<0 ){
- mode_t openMode = 0; /* Permissions to create file with */
-
- fd = robust_open(zName, openFlags, openMode);
- OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
- if( fd<0 && errno!=DFS_STATUS_EISDIR && isReadWrite && !isExclusive ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
- }
- if( fd<0 ){
- rc = rtthreadLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
- goto open_finished;
- }
- }
- assert( fd>=0 );
- if( pOutFlags ){
- *pOutFlags = flags;
- }
-
- if( isDelete ){
- osUnlink(zName);
- }
-#if SQLITE_ENABLE_LOCKING_STYLE
- else{
- p->openFlags = openFlags;
- }
-#endif
-
- noLock = eType!=SQLITE_OPEN_MAIN_DB;
-
- /* Set up appropriate ctrlFlags */
- if( isDelete ) ctrlFlags |= UNIXFILE_DELETE;
- if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY;
- if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK;
- if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC;
- if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
-
- rc = fillInRtthreadFile(pVfs, fd, pFile, zPath, ctrlFlags);
-
-open_finished:
-
- return rc;
-}
-
-
-/*
-** Delete the file at zPath. If the dirSync argument is true, fsync()
-** the directory after deleting the file.
-*/
-static int rtthreadDelete(
- sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */
- const char *zPath, /* Name of file to be deleted */
- int dirSync /* If true, fsync() directory after deleting file */
-){
- int rc = SQLITE_OK;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError(return SQLITE_IOERR_DELETE);
- if( osUnlink(zPath)==(-1) ){
- if( errno==DFS_STATUS_ENOENT ){
- rc = SQLITE_IOERR_DELETE_NOENT;
- }else{
- rc = rtthreadLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
- }
- return rc;
- }
-#ifndef SQLITE_DISABLE_DIRSYNC
- if( (dirSync & 1)!=0 ){
- int fd;
- rc = osOpenDirectory(zPath, &fd);
- if( rc==SQLITE_OK ){
- robust_close(0, fd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
- rc = SQLITE_OK;
- }
- }
-#endif
- return rc;
-}
-
-/*
-** Test the existence of or access permissions of file zPath. The
-** test performed depends on the value of flags:
-**
-** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
-** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
-** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
-**
-** Otherwise return 0.
-*/
-
-#ifndef F_OK
-# define F_OK 0
-#endif
-#ifndef R_OK
-# define R_OK 4
-#endif
-#ifndef W_OK
-# define W_OK 2
-#endif
-
-static int rtthreadAccess(
- sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
- const char *zPath, /* Path of the file to examine */
- int flags, /* What do we want to learn about the zPath file? */
- int *pResOut /* Write result boolean here */
-){
- int amode = 0;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError( return SQLITE_IOERR_ACCESS; );
- switch( flags ){
- case SQLITE_ACCESS_EXISTS:
- amode = F_OK;
- break;
- case SQLITE_ACCESS_READWRITE:
- amode = W_OK|R_OK;
- break;
- case SQLITE_ACCESS_READ:
- amode = R_OK;
- break;
-
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = (osAccess(zPath, amode)==0);
- if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
- struct stat buf;
- if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
- *pResOut = 0;
- }
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname. The relative path
-** is stored as a nul-terminated string in the buffer pointed to by
-** zPath.
-**
-** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes
-** (in this case, MAX_PATHNAME bytes). The full-path is written to
-** this buffer before returning.
-*/
-static int rtthreadFullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zPath, /* Possibly relative input path */
- int nOut, /* Size of output buffer in bytes */
- char *zOut /* Output buffer */
-){
-
- /* 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. This function could fail if, for example, the
- ** current working directory has been unlinked.
- */
- SimulateIOError( return SQLITE_ERROR );
-
- assert( pVfs->mxPathname==MAX_PATHNAME );
- UNUSED_PARAMETER(pVfs);
-
- zOut[nOut-1] = '\0';
- if( zPath[0]=='/' ){
- sqlite3_snprintf(nOut, zOut, "%s", zPath);
- }else{
- int nCwd;
- if( osGetcwd(zOut, nOut-1)==0 ){
- return rtthreadLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
- }
- nCwd = (int)strlen(zOut);
- sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
- }
- return SQLITE_OK;
-}
-
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-# error "rtthread not support load extension, compile with SQLITE_OMIT_WAL."
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define rtthreadDlOpen 0
- #define rtthreadDlError 0
- #define rtthreadDlSym 0
- #define rtthreadDlClose 0
-#endif
-
-/*
-** Write nBuf bytes of random data to the supplied buffer zBuf.
-*/
-static int rtthreadRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
- UNUSED_PARAMETER(NotUsed);
- assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int)));
-
- /* We have to initialize zBuf to prevent valgrind from reporting
- ** errors. The reports issued by valgrind are incorrect - we would
- ** prefer that the randomness be increased by making use of the
- ** uninitialized space in zBuf - but valgrind errors tend to worry
- ** some users. Rather than argue, it seems easier just to initialize
- ** the whole array and silence valgrind, even if that means less randomness
- ** in the random seed.
- **
- ** When testing, initializing zBuf[] to zero is all we do. That means
- ** that we always use the same random number sequence. This makes the
- ** tests repeatable.
- */
- memset(zBuf, 0, nBuf);
- {
- int i;
- char tick8, tick16;
- tick8 = (char)rt_tick_get();
- tick16 = (char)(rt_tick_get() >> 8);
-
- for (i=0; i<nBuf; i++)
- {
- zBuf[i] = (char)(i ^ tick8 ^ tick16);
- tick8 = zBuf[i];
- tick16 = ~(tick8 ^ tick16);
- }
- }
- return nBuf;
-}
-
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-** The argument is the number of microseconds we want to sleep.
-** The return value is the number of microseconds of sleep actually
-** requested from the underlying operating system, a number which
-** might be greater than or equal to the argument, but not less
-** than the argument.
-*/
-static int rtthreadSleep(sqlite3_vfs *NotUsed, int microseconds){
-
- int seconds = (microseconds+999999)/1000000;
- osSleep(seconds * 1000);
- UNUSED_PARAMETER(NotUsed);
- return seconds*1000000;
-}
-
-/*
-** The following variable, if set to a non-zero value, is interpreted as
-** the number of seconds since 1970 and is used to set the result of
-** sqlite3OsCurrentTime() during testing.
-*/
-#ifdef SQLITE_TEST
-int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
-#endif
-
-#ifndef NO_GETTOD
-#define NO_GETTOD 1
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write into *piNow
-** the current time and date as a Julian Day number times 86_400_000. In
-** other words, write into *piNow the number of milliseconds since the Julian
-** epoch of noon in Greenwich on November 24, 4714 B.C according to the
-** proleptic Gregorian calendar.
-**
-** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
-** cannot be found.
-*/
-static int rtthreadCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
- static const sqlite3_int64 rtthreadEpoch = 24405875*(sqlite3_int64)8640000;
- int rc = SQLITE_OK;
-#if defined(NO_GETTOD)
- time_t t;
- time(&t);
- *piNow = ((sqlite3_int64)t)*1000 + rtthreadEpoch;
-#else
- struct timeval sNow;
- if( gettimeofday(&sNow, 0)==0 ){
- *piNow = rtthreadEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
- }else{
- rc = SQLITE_ERROR;
- }
-#endif
-
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *piNow = 1000*(sqlite3_int64)sqlite3_current_time + rtthreadEpoch;
- }
-#endif
- UNUSED_PARAMETER(NotUsed);
- return rc;
-}
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-static int rtthreadCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
- sqlite3_int64 i = 0;
- int rc;
- UNUSED_PARAMETER(NotUsed);
- rc = rtthreadCurrentTimeInt64(0, &i);
- *prNow = i/86400000.0;
- return rc;
-}
-
-/*
-** We added the xGetLastError() method with the intention of providing
-** better low-level error messages when operating-system problems come up
-** during SQLite operation. But so far, none of that has been implemented
-** in the core. So this routine is never called. For now, it is merely
-** a place-holder.
-*/
-static int rtthreadGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
- UNUSED_PARAMETER(NotUsed);
- UNUSED_PARAMETER(NotUsed2);
- UNUSED_PARAMETER(NotUsed3);
- return 0;
-}
-
-
-/*
-************************ End of sqlite3_vfs methods ***************************
-******************************************************************************/
-
-/*
-** Initialize the operating system interface.
-**
-** This routine registers all VFS implementations for unix-like operating
-** systems. This routine, and the sqlite3_os_end() routine that follows,
-** should be the only routines in this file that are visible from other
-** files.
-**
-** This routine is called once during SQLite initialization and by a
-** single thread. The memory allocation and mutex subsystems have not
-** necessarily been initialized when this routine is called, and so they
-** should not be used.
-*/
-/*
- ** The following macro defines an initializer for an sqlite3_vfs object.
- ** The name of the VFS is NAME. The pAppData is a pointer to a pointer
- ** to the "finder" function. (pAppData is a pointer to a pointer because
- ** silly C90 rules prohibit a void* from being cast to a function pointer
- ** and so we have to go through the intermediate pointer to avoid problems
- ** when compiling with -pedantic-errors on GCC.)
- **
- ** The FINDER parameter to this macro is the name of the pointer to the
- ** finder-function. The finder-function returns a pointer to the
- ** sqlite_io_methods object that implements the desired locking
- ** behaviors. See the division above that contains the IOMETHODS
- ** macro for addition information on finder-functions.
- **
- ** Most finders simply return a pointer to a fixed sqlite3_io_methods
- ** object. But the "autolockIoFinder" available on MacOSX does a little
- ** more than that; it looks at the filesystem type that hosts the
- ** database file and tries to choose an locking method appropriate for
- ** that filesystem time.
- */
-#define UNIXVFS(VFSNAME, FINDER) { \
- 3, /* iVersion */ \
- sizeof(rtthreadFile), /* szOsFile */ \
- MAX_PATHNAME, /* mxPathname */ \
- 0, /* pNext */ \
- VFSNAME, /* zName */ \
- (void*)&FINDER, /* pAppData */ \
- rtthreadOpen, /* xOpen */ \
- rtthreadDelete, /* xDelete */ \
- rtthreadAccess, /* xAccess */ \
- rtthreadFullPathname, /* xFullPathname */ \
- rtthreadDlOpen, /* xDlOpen */ \
- rtthreadDlError, /* xDlError */ \
- rtthreadDlSym, /* xDlSym */ \
- rtthreadDlClose, /* xDlClose */ \
- rtthreadRandomness, /* xRandomness */ \
- rtthreadSleep, /* xSleep */ \
- rtthreadCurrentTime, /* xCurrentTime */ \
- rtthreadGetLastError, /* xGetLastError */ \
- rtthreadCurrentTimeInt64, /* xCurrentTimeInt64 */ \
- rtthreadSetSystemCall, /* xSetSystemCall */ \
- rtthreadGetSystemCall, /* xGetSystemCall */ \
- rtthreadNextSystemCall, /* xNextSystemCall */ \
- }
-
-int sqlite3_os_init(void){
- /*
- ** All default VFSes for unix are contained in the following array.
- **
- ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
- ** by the SQLite core when the VFS is registered. So the following
- ** array cannot be const.
- */
- static sqlite3_vfs aVfs[] = {
- UNIXVFS("unix-none", nolockIoFinder ),
- UNIXVFS("unix-dotfile", dotlockIoFinder ),
-#if SQLITE_ENABLE_LOCKING_STYLE
- UNIXVFS("unix-flock", flockIoFinder ),
-#endif
- };
- unsigned int i; /* Loop counter */
-
- /* Double-check that the aSyscall[] array has been constructed
- ** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==24 );
-
- /* Register all VFSes defined in the aVfs[] array */
- for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
- sqlite3_vfs_register(&aVfs[i], i==0);
- }
- return SQLITE_OK;
-}
-
-/*
-** Shutdown the operating system interface.
-**
-** Some operating systems might need to do some cleanup in this routine,
-** to release dynamically allocated objects. But not on unix.
-** This routine is a no-op for unix.
-*/
-int sqlite3_os_end(void){
- return SQLITE_OK;
-}
-
-
-#endif /* SQLITE_OS_RTTHREAD */
-