Updates to the OS/2 implementation from Rich Walsh.

FossilOrigin-Name: dc46156a2237701679433779b871844f4f2abe4b
This commit is contained in:
drh 2011-03-09 11:04:07 +00:00
parent 6f6e689c90
commit a1df4bfc1a
4 changed files with 216 additions and 148 deletions

View File

@ -1,8 +1,8 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Merge\sthe\ssyscall-override\schanges\sinto\strunk.
D 2011-03-08T16:39:29.275
C Updates\sto\sthe\sOS/2\simplementation\sfrom\sRich\sWalsh.
D 2011-03-09T11:04:07.809
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -157,14 +157,14 @@ F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6
F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f
F src/mutex.h fe2ef5e1c4dae531d5a544f9241f19c56d26803d
F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151
F src/mutex_os2.c 6a62583e374ba3ac1a3fcc0da2bfdac7d3942689
F src/mutex_os2.c f5d09e85b914643c230aa97db709fc0db370d93c
F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579
F src/mutex_w32.c 3ade5ae71449d1d023f0ebb3184c2ae6aa9307e4
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863
F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf
F src/os_unix.c 58fe8845678f6a4e30ed6988c5df7327bc7bd69b
F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845
F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1
@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P ddb747d33a004c7fe532a661e879ccba68c79c59 a7d176b27cd73791d45eb3a31df78187ae10ce20
R f6d9df8153eea975bd4c019ada4938a6
P 36d79e6f54cdc4129c6e6366a49722e2cf1cccbd
R 2f4313abc92b495e5c25d9ed87ce7d46
U drh
Z a4115902c8e36dff16feb9c6102d7895
Z fe519f199afd232fa32e880111460489
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFNdlvEoxKgR168RlERAqctAJ0QkDzaXcGb8cYDn6Z1juSfygSdZgCcCoJg
HYxK6HQIevTUFNLB5q3ux8E=
=p3yO
iD8DBQFNd16roxKgR168RlERAjIHAJsFi1zIg+NnkZ8ozYY79qgeXOHlWwCcDItu
3AD87d08lqXy+gxk5jGCRwA=
=eyUa
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
36d79e6f54cdc4129c6e6366a49722e2cf1cccbd
dc46156a2237701679433779b871844f4f2abe4b

View File

@ -31,11 +31,16 @@
struct sqlite3_mutex {
HMTX mutex; /* Mutex controlling the lock */
int id; /* Mutex type */
int nRef; /* Number of references */
TID owner; /* Thread holding this mutex */
#ifdef SQLITE_DEBUG
int trace; /* True to trace changes */
#endif
};
#define OS2_MUTEX_INITIALIZER 0,0,0,0
#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
#endif
/*
** Initialize and deinitialize the mutex subsystem.
@ -51,11 +56,14 @@ static int os2MutexEnd(void){ return SQLITE_OK; }
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li> SQLITE_MUTEX_FAST 0
** <li> SQLITE_MUTEX_RECURSIVE 1
** <li> SQLITE_MUTEX_STATIC_MASTER 2
** <li> SQLITE_MUTEX_STATIC_MEM 3
** <li> SQLITE_MUTEX_STATIC_PRNG 4
** <li> SQLITE_MUTEX_FAST
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
@ -69,7 +77,7 @@ static int os2MutexEnd(void){ return SQLITE_OK; }
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex. Three static mutexes are
** a pointer to a static preexisting mutex. Six static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
** use by SQLite only. Applications that use SQLite mutexes should
@ -99,13 +107,13 @@ static sqlite3_mutex *os2MutexAlloc(int iType){
}
default: {
static volatile int isInit = 0;
static sqlite3_mutex staticMutexes[] = {
{ OS2_MUTEX_INITIALIZER, },
{ OS2_MUTEX_INITIALIZER, },
{ OS2_MUTEX_INITIALIZER, },
{ OS2_MUTEX_INITIALIZER, },
{ OS2_MUTEX_INITIALIZER, },
{ OS2_MUTEX_INITIALIZER, },
static sqlite3_mutex staticMutexes[6] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
};
if ( !isInit ){
APIRET rc;
@ -151,9 +159,14 @@ static sqlite3_mutex *os2MutexAlloc(int iType){
** SQLite is careful to deallocate every mutex that it allocates.
*/
static void os2MutexFree(sqlite3_mutex *p){
if( p==0 ) return;
assert( p->nRef==0 );
#ifdef SQLITE_DEBUG
TID tid;
PID pid;
ULONG ulCount;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
assert( ulCount==0 );
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
#endif
DosCloseMutexSem( p->mutex );
sqlite3_free( p );
}
@ -168,26 +181,29 @@ static int os2MutexHeld(sqlite3_mutex *p){
PID pid;
ULONG ulCount;
PTIB ptib;
if( p!=0 ) {
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
} else {
if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
return 0;
DosGetInfoBlocks(&ptib, NULL);
tid = ptib->tib_ptib2->tib2_ultid;
}
return p==0 || (p->nRef!=0 && p->owner==tid);
return tid==ptib->tib_ptib2->tib2_ultid;
}
static int os2MutexNotheld(sqlite3_mutex *p){
TID tid;
PID pid;
ULONG ulCount;
PTIB ptib;
if( p!= 0 ) {
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
} else {
if( ulCount==0 )
return 1;
DosGetInfoBlocks(&ptib, NULL);
tid = ptib->tib_ptib2->tib2_ultid;
}
return p==0 || p->nRef==0 || p->owner!=tid;
return tid!=ptib->tib_ptib2->tib2_ultid;
}
static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
TID tid;
PID pid;
ULONG ulCount;
DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
}
#endif
@ -203,32 +219,21 @@ static int os2MutexNotheld(sqlite3_mutex *p){
** more than once, the behavior is undefined.
*/
static void os2MutexEnter(sqlite3_mutex *p){
TID tid;
PID holder1;
ULONG holder2;
if( p==0 ) return;
assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
p->owner = tid;
p->nRef++;
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "enter");
#endif
}
static int os2MutexTry(sqlite3_mutex *p){
int rc;
TID tid;
PID holder1;
ULONG holder2;
if( p==0 ) return SQLITE_OK;
int rc = SQLITE_BUSY;
assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) {
DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
p->owner = tid;
p->nRef++;
if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
rc = SQLITE_OK;
} else {
rc = SQLITE_BUSY;
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "try");
#endif
}
return rc;
}
@ -239,19 +244,14 @@ static int os2MutexTry(sqlite3_mutex *p){
** is not currently allocated. SQLite will never do either.
*/
static void os2MutexLeave(sqlite3_mutex *p){
TID tid;
PID holder1;
ULONG holder2;
if( p==0 ) return;
assert( p->nRef>0 );
DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
assert( p->owner==tid );
p->nRef--;
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
assert( os2MutexHeld(p) );
DosReleaseMutexSem(p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ) os2MutexTrace(p, "leave");
#endif
}
sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
static const sqlite3_mutex_methods sMutex = {
os2MutexInit,
os2MutexEnd,
@ -263,6 +263,9 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
#ifdef SQLITE_DEBUG
os2MutexHeld,
os2MutexNotheld
#else
0,
0
#endif
};

View File

@ -647,18 +647,22 @@ char *convertCpPathToUtf8( const char *in ){
*/
static const sqlite3_io_methods os2IoMethod = {
1, /* iVersion */
os2Close,
os2Read,
os2Write,
os2Truncate,
os2Sync,
os2FileSize,
os2Lock,
os2Unlock,
os2CheckReservedLock,
os2FileControl,
os2SectorSize,
os2DeviceCharacteristics
os2Close, /* xClose */
os2Read, /* xRead */
os2Write, /* xWrite */
os2Truncate, /* xTruncate */
os2Sync, /* xSync */
os2FileSize, /* xFileSize */
os2Lock, /* xLock */
os2Unlock, /* xUnlock */
os2CheckReservedLock, /* xCheckReservedLock */
os2FileControl, /* xFileControl */
os2SectorSize, /* xSectorSize */
os2DeviceCharacteristics, /* xDeviceCharacteristics */
0, /* xShmMap */
0, /* xShmLock */
0, /* xShmBarrier */
0 /* xShmUnmap */
};
/***************************************************************************
@ -750,100 +754,137 @@ static int os2FullPathname(
*/
static int os2Open(
sqlite3_vfs *pVfs, /* Not used */
const char *zName, /* Name of the file */
const char *zName, /* Name of the file (UTF-8) */
sqlite3_file *id, /* Write the SQLite file handle here */
int flags, /* Open mode flags */
int *pOutFlags /* Status return flags */
){
HFILE h;
ULONG ulFileAttribute = FILE_NORMAL;
ULONG ulOpenFlags = 0;
ULONG ulOpenMode = 0;
ULONG ulAction = 0;
ULONG rc;
os2File *pFile = (os2File*)id;
APIRET rc = NO_ERROR;
ULONG ulAction;
const char *zUtf8Name = zName;
char *zNameCp;
char zTmpname[CCHMAXPATH+1]; /* Buffer to hold name of temp file */
char zTmpname[CCHMAXPATH];
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
int isCreate = (flags & SQLITE_OPEN_CREATE);
int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
#ifndef NDEBUG
int isReadonly = (flags & SQLITE_OPEN_READONLY);
int eType = (flags & 0xFFFFFF00);
int isOpenJournal = (isCreate && (
eType==SQLITE_OPEN_MASTER_JOURNAL
|| eType==SQLITE_OPEN_MAIN_JOURNAL
|| eType==SQLITE_OPEN_WAL
));
#endif
UNUSED_PARAMETER(pVfs);
assert( id!=0 );
/* 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( pFile, 0, sizeof(*pFile) );
pFile->pMethod = &os2IoMethod;
/* If the second argument to this function is NULL, generate a
** temporary file name to use
*/
if( !zName ){
int rc = getTempname(CCHMAXPATH+1, zTmpname);
if( !zUtf8Name ){
assert(isDelete && !isOpenJournal);
rc = getTempname(CCHMAXPATH, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
}
zName = zTmpname;
zUtf8Name = zTmpname;
}
memset( pFile, 0, sizeof(*pFile) );
OSTRACE(( "OPEN want %d\n", flags ));
if( flags & SQLITE_OPEN_READWRITE ){
if( isReadWrite ){
ulOpenMode |= OPEN_ACCESS_READWRITE;
OSTRACE(( "OPEN read/write\n" ));
}else{
ulOpenMode |= OPEN_ACCESS_READONLY;
OSTRACE(( "OPEN read only\n" ));
}
if( flags & SQLITE_OPEN_CREATE ){
ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
OSTRACE(( "OPEN open new/create\n" ));
}else{
ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
OSTRACE(( "OPEN open existing\n" ));
}
if( flags & SQLITE_OPEN_MAIN_DB ){
ulOpenMode |= OPEN_SHARE_DENYNONE;
OSTRACE(( "OPEN share read/write\n" ));
}else{
ulOpenMode |= OPEN_SHARE_DENYWRITE;
OSTRACE(( "OPEN share read only\n" ));
}
if( flags & SQLITE_OPEN_DELETEONCLOSE ){
char pathUtf8[CCHMAXPATH];
#ifdef NDEBUG /* when debugging we want to make sure it is deleted */
ulFileAttribute = FILE_HIDDEN;
#endif
os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
OSTRACE(( "OPEN hidden/delete on close file attributes\n" ));
}else{
pFile->pathToDel = NULL;
OSTRACE(( "OPEN normal file attribute\n" ));
}
/* always open in random access mode for possibly better speed */
/* Open in random access mode for possibly better speed. Allow full
** sharing because file locks will provide exclusive access when needed.
*/
ulOpenMode |= OPEN_FLAGS_RANDOM;
ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
ulOpenMode |= OPEN_FLAGS_NOINHERIT;
ulOpenMode |= OPEN_SHARE_DENYNONE;
zNameCp = convertUtf8PathToCp( zName );
/* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
** created. SQLite doesn't use it to indicate "exclusive access"
** as it is usually understood.
*/
if( isExclusive ){
/* Creates a new file, only if it does not already exist. */
/* If the file exists, it fails. */
ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
}else if( isCreate ){
/* Open existing file, or create if it doesn't exist */
ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
}else{
/* Opens a file, only if it exists. */
ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
}
/* For DELETEONCLOSE, save a pointer to the converted filename */
if( isDelete ){
char pathUtf8[CCHMAXPATH];
os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 );
pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
}
zNameCp = convertUtf8PathToCp( zUtf8Name );
rc = DosOpen( (PSZ)zNameCp,
&h,
&ulAction,
0L,
ulFileAttribute,
FILE_NORMAL,
ulOpenFlags,
ulOpenMode,
(PEAOP2)NULL );
free( zNameCp );
if( rc != NO_ERROR ){
OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode ));
OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
if( pFile->pathToDel )
free( pFile->pathToDel );
pFile->pathToDel = NULL;
if( flags & SQLITE_OPEN_READWRITE ){
OSTRACE(( "OPEN %d Invalid handle\n",
((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) ));
if( isReadWrite ){
return os2Open( pVfs, zName, id,
((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE),
((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
pOutFlags );
}else{
return SQLITE_CANTOPEN;
@ -851,10 +892,9 @@ static int os2Open(
}
if( pOutFlags ){
*pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
*pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
}
pFile->pMethod = &os2IoMethod;
pFile->h = h;
OpenCounter(+1);
OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
@ -869,13 +909,16 @@ static int os2Delete(
const char *zFilename, /* Name of file to delete */
int syncDir /* Not used on os2 */
){
APIRET rc = NO_ERROR;
char *zFilenameCp = convertUtf8PathToCp( zFilename );
APIRET rc;
char *zFilenameCp;
SimulateIOError( return SQLITE_IOERR_DELETE );
zFilenameCp = convertUtf8PathToCp( zFilename );
rc = DosDelete( (PSZ)zFilenameCp );
free( zFilenameCp );
OSTRACE(( "DELETE \"%s\"\n", zFilename ));
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE;
return (rc == NO_ERROR ||
rc == ERROR_FILE_NOT_FOUND ||
rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE;
}
/*
@ -940,7 +983,7 @@ static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
/* no-op */
}
static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
PFN pfn;
APIRET rc;
rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
@ -952,7 +995,7 @@ static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
strncat(_zSymbol, zSymbol, 255);
rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
}
return rc != NO_ERROR ? 0 : (void*)pfn;
return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
}
static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
DosFreeModule((HMODULE)pHandle);
@ -1056,10 +1099,11 @@ int sqlite3_current_time = 0;
int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
double now;
SHORT minute; /* needs to be able to cope with negative timezone offset */
USHORT second, hour,
USHORT hundredths, second, hour,
day, month, year;
DATETIME dt;
DosGetDateTime( &dt );
hundredths = (USHORT)dt.hundredths;
second = (USHORT)dt.seconds;
minute = (SHORT)dt.minutes + dt.timezone;
hour = (USHORT)dt.hours;
@ -1079,6 +1123,7 @@ int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
now += (hour + 12.0)/24.0;
now += minute/1440.0;
now += second/86400.0;
now += hundredths/8640000.0;
*prNow = now;
#ifdef SQLITE_TEST
if( sqlite3_current_time ){
@ -1088,6 +1133,22 @@ int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
return 0;
}
/*
** 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 0. Return 1 if the time and date cannot be found.
*/
static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
double now;
os2CurrentTime(pVfs, &now);
*piNow = now * 86400000;
return 0;
}
static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
return 0;
}
@ -1097,7 +1158,7 @@ static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
*/
int sqlite3_os_init(void){
static sqlite3_vfs os2Vfs = {
1, /* iVersion */
3, /* iVersion */
sizeof(os2File), /* szOsFile */
CCHMAXPATH, /* mxPathname */
0, /* pNext */
@ -1116,6 +1177,10 @@ int sqlite3_os_init(void){
os2Sleep, /* xSleep */
os2CurrentTime, /* xCurrentTime */
os2GetLastError, /* xGetLastError */
os2CurrentTimeInt64 /* xCurrentTimeInt64 */
0, /* xSetSystemCall */
0, /* xGetSystemCall */
0, /* xNextSystemCall */
};
sqlite3_vfs_register(&os2Vfs, 1);
initUconvObjects();