1/* 2** 2006 Feb 14 3** 4** The author disclaims copyright to this source code. In place of 5** a legal notice, here is a blessing: 6** 7** May you do good and not evil. 8** May you find forgiveness for yourself and forgive others. 9** May you share freely, never taking more than you give. 10** 11****************************************************************************** 12** 13** This file contains code that is specific to OS/2. 14*/ 15 16#include "sqliteInt.h" 17 18#if SQLITE_OS_OS2 19 20/* 21** A Note About Memory Allocation: 22** 23** This driver uses malloc()/free() directly rather than going through 24** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers 25** are designed for use on embedded systems where memory is scarce and 26** malloc failures happen frequently. OS/2 does not typically run on 27** embedded systems, and when it does the developers normally have bigger 28** problems to worry about than running out of memory. So there is not 29** a compelling need to use the wrappers. 30** 31** But there is a good reason to not use the wrappers. If we use the 32** wrappers then we will get simulated malloc() failures within this 33** driver. And that causes all kinds of problems for our tests. We 34** could enhance SQLite to deal with simulated malloc failures within 35** the OS driver, but the code to deal with those failure would not 36** be exercised on Linux (which does not need to malloc() in the driver) 37** and so we would have difficulty writing coverage tests for that 38** code. Better to leave the code out, we think. 39** 40** The point of this discussion is as follows: When creating a new 41** OS layer for an embedded system, if you use this file as an example, 42** avoid the use of malloc()/free(). Those routines work ok on OS/2 43** desktops but not so well in embedded systems. 44*/ 45 46/* 47** Macros used to determine whether or not to use threads. 48*/ 49#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE 50# define SQLITE_OS2_THREADS 1 51#endif 52 53/* 54** Include code that is common to all os_*.c files 55*/ 56#include "os_common.h" 57 58/* Forward references */ 59typedef struct os2File os2File; /* The file structure */ 60typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */ 61typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */ 62 63/* 64** The os2File structure is subclass of sqlite3_file specific for the OS/2 65** protability layer. 66*/ 67struct os2File { 68 const sqlite3_io_methods *pMethod; /* Always the first entry */ 69 HFILE h; /* Handle for accessing the file */ 70 int flags; /* Flags provided to os2Open() */ 71 int locktype; /* Type of lock currently held on this file */ 72 int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ 73 char *zFullPathCp; /* Full path name of this file */ 74 os2ShmLink *pShmLink; /* Instance of shared memory on this file */ 75}; 76 77#define LOCK_TIMEOUT 10L /* the default locking timeout */ 78 79/* 80** Missing from some versions of the OS/2 toolkit - 81** used to allocate from high memory if possible 82*/ 83#ifndef OBJ_ANY 84# define OBJ_ANY 0x00000400 85#endif 86 87/***************************************************************************** 88** The next group of routines implement the I/O methods specified 89** by the sqlite3_io_methods object. 90******************************************************************************/ 91 92/* 93** Close a file. 94*/ 95static int os2Close( sqlite3_file *id ){ 96 APIRET rc; 97 os2File *pFile = (os2File*)id; 98 99 assert( id!=0 ); 100 OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp )); 101 102 rc = DosClose( pFile->h ); 103 104 if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE ) 105 DosForceDelete( (PSZ)pFile->zFullPathCp ); 106 107 free( pFile->zFullPathCp ); 108 pFile->zFullPathCp = NULL; 109 pFile->locktype = NO_LOCK; 110 pFile->h = (HFILE)-1; 111 pFile->flags = 0; 112 113 OpenCounter( -1 ); 114 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; 115} 116 117/* 118** Read data from a file into a buffer. Return SQLITE_OK if all 119** bytes were read successfully and SQLITE_IOERR if anything goes 120** wrong. 121*/ 122static int os2Read( 123 sqlite3_file *id, /* File to read from */ 124 void *pBuf, /* Write content into this buffer */ 125 int amt, /* Number of bytes to read */ 126 sqlite3_int64 offset /* Begin reading at this offset */ 127){ 128 ULONG fileLocation = 0L; 129 ULONG got; 130 os2File *pFile = (os2File*)id; 131 assert( id!=0 ); 132 SimulateIOError( return SQLITE_IOERR_READ ); 133 OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype )); 134 if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ 135 return SQLITE_IOERR; 136 } 137 if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){ 138 return SQLITE_IOERR_READ; 139 } 140 if( got == (ULONG)amt ) 141 return SQLITE_OK; 142 else { 143 /* Unread portions of the input buffer must be zero-filled */ 144 memset(&((char*)pBuf)[got], 0, amt-got); 145 return SQLITE_IOERR_SHORT_READ; 146 } 147} 148 149/* 150** Write data from a buffer into a file. Return SQLITE_OK on success 151** or some other error code on failure. 152*/ 153static int os2Write( 154 sqlite3_file *id, /* File to write into */ 155 const void *pBuf, /* The bytes to be written */ 156 int amt, /* Number of bytes to write */ 157 sqlite3_int64 offset /* Offset into the file to begin writing at */ 158){ 159 ULONG fileLocation = 0L; 160 APIRET rc = NO_ERROR; 161 ULONG wrote; 162 os2File *pFile = (os2File*)id; 163 assert( id!=0 ); 164 SimulateIOError( return SQLITE_IOERR_WRITE ); 165 SimulateDiskfullError( return SQLITE_FULL ); 166 OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype )); 167 if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ 168 return SQLITE_IOERR; 169 } 170 assert( amt>0 ); 171 while( amt > 0 && 172 ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR && 173 wrote > 0 174 ){ 175 amt -= wrote; 176 pBuf = &((char*)pBuf)[wrote]; 177 } 178 179 return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK; 180} 181 182/* 183** Truncate an open file to a specified size 184*/ 185static int os2Truncate( sqlite3_file *id, i64 nByte ){ 186 APIRET rc; 187 os2File *pFile = (os2File*)id; 188 assert( id!=0 ); 189 OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte )); 190 SimulateIOError( return SQLITE_IOERR_TRUNCATE ); 191 192 /* If the user has configured a chunk-size for this file, truncate the 193 ** file so that it consists of an integer number of chunks (i.e. the 194 ** actual file size after the operation may be larger than the requested 195 ** size). 196 */ 197 if( pFile->szChunk ){ 198 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; 199 } 200 201 rc = DosSetFileSize( pFile->h, nByte ); 202 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE; 203} 204 205#ifdef SQLITE_TEST 206/* 207** Count the number of fullsyncs and normal syncs. This is used to test 208** that syncs and fullsyncs are occuring at the right times. 209*/ 210int sqlite3_sync_count = 0; 211int sqlite3_fullsync_count = 0; 212#endif 213 214/* 215** Make sure all writes to a particular file are committed to disk. 216*/ 217static int os2Sync( sqlite3_file *id, int flags ){ 218 os2File *pFile = (os2File*)id; 219 OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype )); 220#ifdef SQLITE_TEST 221 if( flags & SQLITE_SYNC_FULL){ 222 sqlite3_fullsync_count++; 223 } 224 sqlite3_sync_count++; 225#endif 226 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a 227 ** no-op 228 */ 229#ifdef SQLITE_NO_SYNC 230 UNUSED_PARAMETER(pFile); 231 return SQLITE_OK; 232#else 233 return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; 234#endif 235} 236 237/* 238** Determine the current size of a file in bytes 239*/ 240static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){ 241 APIRET rc = NO_ERROR; 242 FILESTATUS3 fsts3FileInfo; 243 memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); 244 assert( id!=0 ); 245 SimulateIOError( return SQLITE_IOERR_FSTAT ); 246 rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); 247 if( rc == NO_ERROR ){ 248 *pSize = fsts3FileInfo.cbFile; 249 return SQLITE_OK; 250 }else{ 251 return SQLITE_IOERR_FSTAT; 252 } 253} 254 255/* 256** Acquire a reader lock. 257*/ 258static int getReadLock( os2File *pFile ){ 259 FILELOCK LockArea, 260 UnlockArea; 261 APIRET res; 262 memset(&LockArea, 0, sizeof(LockArea)); 263 memset(&UnlockArea, 0, sizeof(UnlockArea)); 264 LockArea.lOffset = SHARED_FIRST; 265 LockArea.lRange = SHARED_SIZE; 266 UnlockArea.lOffset = 0L; 267 UnlockArea.lRange = 0L; 268 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); 269 OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res )); 270 return res; 271} 272 273/* 274** Undo a readlock 275*/ 276static int unlockReadLock( os2File *id ){ 277 FILELOCK LockArea, 278 UnlockArea; 279 APIRET res; 280 memset(&LockArea, 0, sizeof(LockArea)); 281 memset(&UnlockArea, 0, sizeof(UnlockArea)); 282 LockArea.lOffset = 0L; 283 LockArea.lRange = 0L; 284 UnlockArea.lOffset = SHARED_FIRST; 285 UnlockArea.lRange = SHARED_SIZE; 286 res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); 287 OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res )); 288 return res; 289} 290 291/* 292** Lock the file with the lock specified by parameter locktype - one 293** of the following: 294** 295** (1) SHARED_LOCK 296** (2) RESERVED_LOCK 297** (3) PENDING_LOCK 298** (4) EXCLUSIVE_LOCK 299** 300** Sometimes when requesting one lock state, additional lock states 301** are inserted in between. The locking might fail on one of the later 302** transitions leaving the lock state different from what it started but 303** still short of its goal. The following chart shows the allowed 304** transitions and the inserted intermediate states: 305** 306** UNLOCKED -> SHARED 307** SHARED -> RESERVED 308** SHARED -> (PENDING) -> EXCLUSIVE 309** RESERVED -> (PENDING) -> EXCLUSIVE 310** PENDING -> EXCLUSIVE 311** 312** This routine will only increase a lock. The os2Unlock() routine 313** erases all locks at once and returns us immediately to locking level 0. 314** It is not possible to lower the locking level one step at a time. You 315** must go straight to locking level 0. 316*/ 317static int os2Lock( sqlite3_file *id, int locktype ){ 318 int rc = SQLITE_OK; /* Return code from subroutines */ 319 APIRET res = NO_ERROR; /* Result of an OS/2 lock call */ 320 int newLocktype; /* Set pFile->locktype to this value before exiting */ 321 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ 322 FILELOCK LockArea, 323 UnlockArea; 324 os2File *pFile = (os2File*)id; 325 memset(&LockArea, 0, sizeof(LockArea)); 326 memset(&UnlockArea, 0, sizeof(UnlockArea)); 327 assert( pFile!=0 ); 328 OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype )); 329 330 /* If there is already a lock of this type or more restrictive on the 331 ** os2File, do nothing. Don't use the end_lock: exit path, as 332 ** sqlite3_mutex_enter() hasn't been called yet. 333 */ 334 if( pFile->locktype>=locktype ){ 335 OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype )); 336 return SQLITE_OK; 337 } 338 339 /* Make sure the locking sequence is correct 340 */ 341 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); 342 assert( locktype!=PENDING_LOCK ); 343 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); 344 345 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or 346 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of 347 ** the PENDING_LOCK byte is temporary. 348 */ 349 newLocktype = pFile->locktype; 350 if( pFile->locktype==NO_LOCK 351 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) 352 ){ 353 LockArea.lOffset = PENDING_BYTE; 354 LockArea.lRange = 1L; 355 UnlockArea.lOffset = 0L; 356 UnlockArea.lRange = 0L; 357 358 /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */ 359 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L ); 360 if( res == NO_ERROR ){ 361 gotPendingLock = 1; 362 OSTRACE(( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res )); 363 } 364 } 365 366 /* Acquire a shared lock 367 */ 368 if( locktype==SHARED_LOCK && res == NO_ERROR ){ 369 assert( pFile->locktype==NO_LOCK ); 370 res = getReadLock(pFile); 371 if( res == NO_ERROR ){ 372 newLocktype = SHARED_LOCK; 373 } 374 OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res )); 375 } 376 377 /* Acquire a RESERVED lock 378 */ 379 if( locktype==RESERVED_LOCK && res == NO_ERROR ){ 380 assert( pFile->locktype==SHARED_LOCK ); 381 LockArea.lOffset = RESERVED_BYTE; 382 LockArea.lRange = 1L; 383 UnlockArea.lOffset = 0L; 384 UnlockArea.lRange = 0L; 385 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 386 if( res == NO_ERROR ){ 387 newLocktype = RESERVED_LOCK; 388 } 389 OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res )); 390 } 391 392 /* Acquire a PENDING lock 393 */ 394 if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ 395 newLocktype = PENDING_LOCK; 396 gotPendingLock = 0; 397 OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n", 398 pFile->h )); 399 } 400 401 /* Acquire an EXCLUSIVE lock 402 */ 403 if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ 404 assert( pFile->locktype>=SHARED_LOCK ); 405 res = unlockReadLock(pFile); 406 OSTRACE(( "unreadlock = %d\n", res )); 407 LockArea.lOffset = SHARED_FIRST; 408 LockArea.lRange = SHARED_SIZE; 409 UnlockArea.lOffset = 0L; 410 UnlockArea.lRange = 0L; 411 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 412 if( res == NO_ERROR ){ 413 newLocktype = EXCLUSIVE_LOCK; 414 }else{ 415 OSTRACE(( "OS/2 error-code = %d\n", res )); 416 getReadLock(pFile); 417 } 418 OSTRACE(( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res )); 419 } 420 421 /* If we are holding a PENDING lock that ought to be released, then 422 ** release it now. 423 */ 424 if( gotPendingLock && locktype==SHARED_LOCK ){ 425 int r; 426 LockArea.lOffset = 0L; 427 LockArea.lRange = 0L; 428 UnlockArea.lOffset = PENDING_BYTE; 429 UnlockArea.lRange = 1L; 430 r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 431 OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r )); 432 } 433 434 /* Update the state of the lock has held in the file descriptor then 435 ** return the appropriate result code. 436 */ 437 if( res == NO_ERROR ){ 438 rc = SQLITE_OK; 439 }else{ 440 OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, 441 locktype, newLocktype )); 442 rc = SQLITE_BUSY; 443 } 444 pFile->locktype = newLocktype; 445 OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype )); 446 return rc; 447} 448 449/* 450** This routine checks if there is a RESERVED lock held on the specified 451** file by this or any other process. If such a lock is held, return 452** non-zero, otherwise zero. 453*/ 454static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ 455 int r = 0; 456 os2File *pFile = (os2File*)id; 457 assert( pFile!=0 ); 458 if( pFile->locktype>=RESERVED_LOCK ){ 459 r = 1; 460 OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r )); 461 }else{ 462 FILELOCK LockArea, 463 UnlockArea; 464 APIRET rc = NO_ERROR; 465 memset(&LockArea, 0, sizeof(LockArea)); 466 memset(&UnlockArea, 0, sizeof(UnlockArea)); 467 LockArea.lOffset = RESERVED_BYTE; 468 LockArea.lRange = 1L; 469 UnlockArea.lOffset = 0L; 470 UnlockArea.lRange = 0L; 471 rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 472 OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc )); 473 if( rc == NO_ERROR ){ 474 APIRET rcu = NO_ERROR; /* return code for unlocking */ 475 LockArea.lOffset = 0L; 476 LockArea.lRange = 0L; 477 UnlockArea.lOffset = RESERVED_BYTE; 478 UnlockArea.lRange = 1L; 479 rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 480 OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu )); 481 } 482 r = !(rc == NO_ERROR); 483 OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r )); 484 } 485 *pOut = r; 486 return SQLITE_OK; 487} 488 489/* 490** Lower the locking level on file descriptor id to locktype. locktype 491** must be either NO_LOCK or SHARED_LOCK. 492** 493** If the locking level of the file descriptor is already at or below 494** the requested locking level, this routine is a no-op. 495** 496** It is not possible for this routine to fail if the second argument 497** is NO_LOCK. If the second argument is SHARED_LOCK then this routine 498** might return SQLITE_IOERR; 499*/ 500static int os2Unlock( sqlite3_file *id, int locktype ){ 501 int type; 502 os2File *pFile = (os2File*)id; 503 APIRET rc = SQLITE_OK; 504 APIRET res = NO_ERROR; 505 FILELOCK LockArea, 506 UnlockArea; 507 memset(&LockArea, 0, sizeof(LockArea)); 508 memset(&UnlockArea, 0, sizeof(UnlockArea)); 509 assert( pFile!=0 ); 510 assert( locktype<=SHARED_LOCK ); 511 OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype )); 512 type = pFile->locktype; 513 if( type>=EXCLUSIVE_LOCK ){ 514 LockArea.lOffset = 0L; 515 LockArea.lRange = 0L; 516 UnlockArea.lOffset = SHARED_FIRST; 517 UnlockArea.lRange = SHARED_SIZE; 518 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 519 OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res )); 520 if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ 521 /* This should never happen. We should always be able to 522 ** reacquire the read lock */ 523 OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype )); 524 rc = SQLITE_IOERR_UNLOCK; 525 } 526 } 527 if( type>=RESERVED_LOCK ){ 528 LockArea.lOffset = 0L; 529 LockArea.lRange = 0L; 530 UnlockArea.lOffset = RESERVED_BYTE; 531 UnlockArea.lRange = 1L; 532 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 533 OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res )); 534 } 535 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ 536 res = unlockReadLock(pFile); 537 OSTRACE(( "UNLOCK %d is %d want %d res=%d\n", 538 pFile->h, type, locktype, res )); 539 } 540 if( type>=PENDING_LOCK ){ 541 LockArea.lOffset = 0L; 542 LockArea.lRange = 0L; 543 UnlockArea.lOffset = PENDING_BYTE; 544 UnlockArea.lRange = 1L; 545 res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); 546 OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res )); 547 } 548 pFile->locktype = locktype; 549 OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype )); 550 return rc; 551} 552 553/* 554** Control and query of the open file handle. 555*/ 556static int os2FileControl(sqlite3_file *id, int op, void *pArg){ 557 switch( op ){ 558 case SQLITE_FCNTL_LOCKSTATE: { 559 *(int*)pArg = ((os2File*)id)->locktype; 560 OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n", 561 ((os2File*)id)->h, ((os2File*)id)->locktype )); 562 return SQLITE_OK; 563 } 564 case SQLITE_FCNTL_CHUNK_SIZE: { 565 ((os2File*)id)->szChunk = *(int*)pArg; 566 return SQLITE_OK; 567 } 568 case SQLITE_FCNTL_SIZE_HINT: { 569 sqlite3_int64 sz = *(sqlite3_int64*)pArg; 570 SimulateIOErrorBenign(1); 571 os2Truncate(id, sz); 572 SimulateIOErrorBenign(0); 573 return SQLITE_OK; 574 } 575 case SQLITE_FCNTL_SYNC_OMITTED: { 576 return SQLITE_OK; 577 } 578 } 579 return SQLITE_NOTFOUND; 580} 581 582/* 583** Return the sector size in bytes of the underlying block device for 584** the specified file. This is almost always 512 bytes, but may be 585** larger for some devices. 586** 587** SQLite code assumes this function cannot fail. It also assumes that 588** if two files are created in the same file-system directory (i.e. 589** a database and its journal file) that the sector size will be the 590** same for both. 591*/ 592static int os2SectorSize(sqlite3_file *id){ 593 UNUSED_PARAMETER(id); 594 return SQLITE_DEFAULT_SECTOR_SIZE; 595} 596 597/* 598** Return a vector of device characteristics. 599*/ 600static int os2DeviceCharacteristics(sqlite3_file *id){ 601 UNUSED_PARAMETER(id); 602 return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; 603} 604 605 606/* 607** Character set conversion objects used by conversion routines. 608*/ 609static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */ 610static UconvObject uclCp = NULL; /* convert between local codepage and UCS-2 */ 611 612/* 613** Helper function to initialize the conversion objects from and to UTF-8. 614*/ 615static void initUconvObjects( void ){ 616 if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS ) 617 ucUtf8 = NULL; 618 if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS ) 619 uclCp = NULL; 620} 621 622/* 623** Helper function to free the conversion objects from and to UTF-8. 624*/ 625static void freeUconvObjects( void ){ 626 if ( ucUtf8 ) 627 UniFreeUconvObject( ucUtf8 ); 628 if ( uclCp ) 629 UniFreeUconvObject( uclCp ); 630 ucUtf8 = NULL; 631 uclCp = NULL; 632} 633 634/* 635** Helper function to convert UTF-8 filenames to local OS/2 codepage. 636** The two-step process: first convert the incoming UTF-8 string 637** into UCS-2 and then from UCS-2 to the current codepage. 638** The returned char pointer has to be freed. 639*/ 640static char *convertUtf8PathToCp( const char *in ){ 641 UniChar tempPath[CCHMAXPATH]; 642 char *out = (char *)calloc( CCHMAXPATH, 1 ); 643 644 if( !out ) 645 return NULL; 646 647 if( !ucUtf8 || !uclCp ) 648 initUconvObjects(); 649 650 /* determine string for the conversion of UTF-8 which is CP1208 */ 651 if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) 652 return out; /* if conversion fails, return the empty string */ 653 654 /* conversion for current codepage which can be used for paths */ 655 UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH ); 656 657 return out; 658} 659 660/* 661** Helper function to convert filenames from local codepage to UTF-8. 662** The two-step process: first convert the incoming codepage-specific 663** string into UCS-2 and then from UCS-2 to the codepage of UTF-8. 664** The returned char pointer has to be freed. 665** 666** This function is non-static to be able to use this in shell.c and 667** similar applications that take command line arguments. 668*/ 669char *convertCpPathToUtf8( const char *in ){ 670 UniChar tempPath[CCHMAXPATH]; 671 char *out = (char *)calloc( CCHMAXPATH, 1 ); 672 673 if( !out ) 674 return NULL; 675 676 if( !ucUtf8 || !uclCp ) 677 initUconvObjects(); 678 679 /* conversion for current codepage which can be used for paths */ 680 if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) 681 return out; /* if conversion fails, return the empty string */ 682 683 /* determine string for the conversion of UTF-8 which is CP1208 */ 684 UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH ); 685 686 return out; 687} 688 689 690#ifndef SQLITE_OMIT_WAL 691 692/* 693** Use main database file for interprocess locking. If un-defined 694** a separate file is created for this purpose. The file will be 695** used only to set file locks. There will be no data written to it. 696*/ 697#define SQLITE_OS2_NO_WAL_LOCK_FILE 698 699#if 0 700static void _ERR_TRACE( const char *fmt, ... ) { 701 va_list ap; 702 va_start(ap, fmt); 703 vfprintf(stderr, fmt, ap); 704 fflush(stderr); 705} 706#define ERR_TRACE(rc, msg) \ 707 if( (rc) != SQLITE_OK ) _ERR_TRACE msg; 708#else 709#define ERR_TRACE(rc, msg) 710#endif 711 712/* 713** Helper functions to obtain and relinquish the global mutex. The 714** global mutex is used to protect os2ShmNodeList. 715** 716** Function os2ShmMutexHeld() is used to assert() that the global mutex 717** is held when required. This function is only used as part of assert() 718** statements. e.g. 719** 720** os2ShmEnterMutex() 721** assert( os2ShmMutexHeld() ); 722** os2ShmLeaveMutex() 723*/ 724static void os2ShmEnterMutex(void){ 725 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); 726} 727static void os2ShmLeaveMutex(void){ 728 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); 729} 730#ifdef SQLITE_DEBUG 731static int os2ShmMutexHeld(void) { 732 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); 733} 734int GetCurrentProcessId(void) { 735 PPIB pib; 736 DosGetInfoBlocks(NULL, &pib); 737 return (int)pib->pib_ulpid; 738} 739#endif 740 741/* 742** Object used to represent a the shared memory area for a single log file. 743** When multiple threads all reference the same log-summary, each thread has 744** its own os2File object, but they all point to a single instance of this 745** object. In other words, each log-summary is opened only once per process. 746** 747** os2ShmMutexHeld() must be true when creating or destroying 748** this object or while reading or writing the following fields: 749** 750** nRef 751** pNext 752** 753** The following fields are read-only after the object is created: 754** 755** szRegion 756** hLockFile 757** shmBaseName 758** 759** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and 760** os2ShmMutexHeld() is true when reading or writing any other field 761** in this structure. 762** 763*/ 764struct os2ShmNode { 765 sqlite3_mutex *mutex; /* Mutex to access this object */ 766 os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */ 767 768 int szRegion; /* Size of shared-memory regions */ 769 770 int nRegion; /* Size of array apRegion */ 771 void **apRegion; /* Array of pointers to shared-memory regions */ 772 773 int nRef; /* Number of os2ShmLink objects pointing to this */ 774 os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */ 775 776 HFILE hLockFile; /* File used for inter-process memory locking */ 777 char shmBaseName[1]; /* Name of the memory object !!! must last !!! */ 778}; 779 780 781/* 782** Structure used internally by this VFS to record the state of an 783** open shared memory connection. 784** 785** The following fields are initialized when this object is created and 786** are read-only thereafter: 787** 788** os2Shm.pShmNode 789** os2Shm.id 790** 791** All other fields are read/write. The os2Shm.pShmNode->mutex must be held 792** while accessing any read/write fields. 793*/ 794struct os2ShmLink { 795 os2ShmNode *pShmNode; /* The underlying os2ShmNode object */ 796 os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */ 797 u32 sharedMask; /* Mask of shared locks held */ 798 u32 exclMask; /* Mask of exclusive locks held */ 799#ifdef SQLITE_DEBUG 800 u8 id; /* Id of this connection with its os2ShmNode */ 801#endif 802}; 803 804 805/* 806** A global list of all os2ShmNode objects. 807** 808** The os2ShmMutexHeld() must be true while reading or writing this list. 809*/ 810static os2ShmNode *os2ShmNodeList = NULL; 811 812/* 813** Constants used for locking 814*/ 815#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE 816#define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */ 817#else 818#define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ 819#endif 820 821#define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ 822 823/* 824** Apply advisory locks for all n bytes beginning at ofst. 825*/ 826#define _SHM_UNLCK 1 /* no lock */ 827#define _SHM_RDLCK 2 /* shared lock, no wait */ 828#define _SHM_WRLCK 3 /* exlusive lock, no wait */ 829#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */ 830static int os2ShmSystemLock( 831 os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */ 832 int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */ 833 int ofst, /* Offset to first byte to be locked/unlocked */ 834 int nByte /* Number of bytes to lock or unlock */ 835){ 836 APIRET rc; 837 FILELOCK area; 838 ULONG mode, timeout; 839 840 /* Access to the os2ShmNode object is serialized by the caller */ 841 assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 ); 842 843 mode = 1; /* shared lock */ 844 timeout = 0; /* no wait */ 845 area.lOffset = ofst; 846 area.lRange = nByte; 847 848 switch( lockType ) { 849 case _SHM_WRLCK_WAIT: 850 timeout = (ULONG)-1; /* wait forever */ 851 case _SHM_WRLCK: 852 mode = 0; /* exclusive lock */ 853 case _SHM_RDLCK: 854 rc = DosSetFileLocks(pNode->hLockFile, 855 NULL, &area, timeout, mode); 856 break; 857 /* case _SHM_UNLCK: */ 858 default: 859 rc = DosSetFileLocks(pNode->hLockFile, 860 &area, NULL, 0, 0); 861 break; 862 } 863 864 OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 865 pNode->hLockFile, 866 rc==SQLITE_OK ? "ok" : "failed", 867 lockType==_SHM_UNLCK ? "Unlock" : "Lock", 868 rc)); 869 870 ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName)) 871 872 return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY; 873} 874 875/* 876** Find an os2ShmNode in global list or allocate a new one, if not found. 877** 878** This is not a VFS shared-memory method; it is a utility function called 879** by VFS shared-memory methods. 880*/ 881static int os2OpenSharedMemory( os2File *fd, int szRegion ) { 882 os2ShmLink *pLink; 883 os2ShmNode *pNode; 884 int cbShmName, rc = SQLITE_OK; 885 char shmName[CCHMAXPATH + 30]; 886#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE 887 ULONG action; 888#endif 889 890 /* We need some additional space at the end to append the region number */ 891 cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp ); 892 if( cbShmName >= CCHMAXPATH-8 ) 893 return SQLITE_IOERR_SHMOPEN; 894 895 /* Replace colon in file name to form a valid shared memory name */ 896 shmName[10+1] = '!'; 897 898 /* Allocate link object (we free it later in case of failure) */ 899 pLink = sqlite3_malloc( sizeof(*pLink) ); 900 if( !pLink ) 901 return SQLITE_NOMEM; 902 903 /* Access node list */ 904 os2ShmEnterMutex(); 905 906 /* Find node by it's shared memory base name */ 907 for( pNode = os2ShmNodeList; 908 pNode && stricmp(shmName, pNode->shmBaseName) != 0; 909 pNode = pNode->pNext ) ; 910 911 /* Not found: allocate a new node */ 912 if( !pNode ) { 913 pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName ); 914 if( pNode ) { 915 memset(pNode, 0, sizeof(*pNode) ); 916 pNode->szRegion = szRegion; 917 pNode->hLockFile = (HFILE)-1; 918 strcpy(pNode->shmBaseName, shmName); 919 920#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE 921 if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) { 922#else 923 sprintf(shmName, "%s-lck", fd->zFullPathCp); 924 if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, 925 OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW, 926 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | 927 OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR, 928 NULL) != 0 ) { 929#endif 930 sqlite3_free(pNode); 931 rc = SQLITE_IOERR; 932 } else { 933 pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); 934 if( !pNode->mutex ) { 935 sqlite3_free(pNode); 936 rc = SQLITE_NOMEM; 937 } 938 } 939 } else { 940 rc = SQLITE_NOMEM; 941 } 942 943 if( rc == SQLITE_OK ) { 944 pNode->pNext = os2ShmNodeList; 945 os2ShmNodeList = pNode; 946 } else { 947 pNode = NULL; 948 } 949 } else if( pNode->szRegion != szRegion ) { 950 rc = SQLITE_IOERR_SHMSIZE; 951 pNode = NULL; 952 } 953 954 if( pNode ) { 955 sqlite3_mutex_enter(pNode->mutex); 956 957 memset(pLink, 0, sizeof(*pLink)); 958 959 pLink->pShmNode = pNode; 960 pLink->pNext = pNode->pFirst; 961 pNode->pFirst = pLink; 962 pNode->nRef++; 963 964 fd->pShmLink = pLink; 965 966 sqlite3_mutex_leave(pNode->mutex); 967 968 } else { 969 /* Error occured. Free our link object. */ 970 sqlite3_free(pLink); 971 } 972 973 os2ShmLeaveMutex(); 974 975 ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp)) 976 977 return rc; 978} 979 980/* 981** Purge the os2ShmNodeList list of all entries with nRef==0. 982** 983** This is not a VFS shared-memory method; it is a utility function called 984** by VFS shared-memory methods. 985*/ 986static void os2PurgeShmNodes( int deleteFlag ) { 987 os2ShmNode *pNode; 988 os2ShmNode **ppNode; 989 990 os2ShmEnterMutex(); 991 992 ppNode = &os2ShmNodeList; 993 994 while( *ppNode ) { 995 pNode = *ppNode; 996 997 if( pNode->nRef == 0 ) { 998 *ppNode = pNode->pNext; 999 1000 if( pNode->apRegion ) { 1001 /* Prevent other processes from resizing the shared memory */ 1002 os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); 1003 1004 while( pNode->nRegion-- ) { 1005#ifdef SQLITE_DEBUG 1006 int rc = 1007#endif 1008 DosFreeMem(pNode->apRegion[pNode->nRegion]); 1009 1010 OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", 1011 (int)GetCurrentProcessId(), pNode->nRegion, 1012 rc == 0 ? "ok" : "failed")); 1013 } 1014 1015 /* Allow other processes to resize the shared memory */ 1016 os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); 1017 1018 sqlite3_free(pNode->apRegion); 1019 } 1020 1021 DosClose(pNode->hLockFile); 1022 1023#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE 1024 if( deleteFlag ) { 1025 char fileName[CCHMAXPATH]; 1026 /* Skip "\\SHAREMEM\\" */ 1027 sprintf(fileName, "%s-lck", pNode->shmBaseName + 10); 1028 /* restore colon */ 1029 fileName[1] = ':'; 1030 1031 DosForceDelete(fileName); 1032 } 1033#endif 1034 1035 sqlite3_mutex_free(pNode->mutex); 1036 1037 sqlite3_free(pNode); 1038 1039 } else { 1040 ppNode = &pNode->pNext; 1041 } 1042 } 1043 1044 os2ShmLeaveMutex(); 1045} 1046 1047/* 1048** This function is called to obtain a pointer to region iRegion of the 1049** shared-memory associated with the database file id. Shared-memory regions 1050** are numbered starting from zero. Each shared-memory region is szRegion 1051** bytes in size. 1052** 1053** If an error occurs, an error code is returned and *pp is set to NULL. 1054** 1055** Otherwise, if the bExtend parameter is 0 and the requested shared-memory 1056** region has not been allocated (by any client, including one running in a 1057** separate process), then *pp is set to NULL and SQLITE_OK returned. If 1058** bExtend is non-zero and the requested shared-memory region has not yet 1059** been allocated, it is allocated by this function. 1060** 1061** If the shared-memory region has already been allocated or is allocated by 1062** this call as described above, then it is mapped into this processes 1063** address space (if it is not already), *pp is set to point to the mapped 1064** memory and SQLITE_OK returned. 1065*/ 1066static int os2ShmMap( 1067 sqlite3_file *id, /* Handle open on database file */ 1068 int iRegion, /* Region to retrieve */ 1069 int szRegion, /* Size of regions */ 1070 int bExtend, /* True to extend block if necessary */ 1071 void volatile **pp /* OUT: Mapped memory */ 1072){ 1073 PVOID pvTemp; 1074 void **apRegion; 1075 os2ShmNode *pNode; 1076 int n, rc = SQLITE_OK; 1077 char shmName[CCHMAXPATH]; 1078 os2File *pFile = (os2File*)id; 1079 1080 *pp = NULL; 1081 1082 if( !pFile->pShmLink ) 1083 rc = os2OpenSharedMemory( pFile, szRegion ); 1084 1085 if( rc == SQLITE_OK ) { 1086 pNode = pFile->pShmLink->pShmNode ; 1087 1088 sqlite3_mutex_enter(pNode->mutex); 1089 1090 assert( szRegion==pNode->szRegion ); 1091 1092 /* Unmapped region ? */ 1093 if( iRegion >= pNode->nRegion ) { 1094 /* Prevent other processes from resizing the shared memory */ 1095 os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); 1096 1097 apRegion = sqlite3_realloc( 1098 pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0])); 1099 1100 if( apRegion ) { 1101 pNode->apRegion = apRegion; 1102 1103 while( pNode->nRegion <= iRegion ) { 1104 sprintf(shmName, "%s-%u", 1105 pNode->shmBaseName, pNode->nRegion); 1106 1107 if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, 1108 PAG_READ | PAG_WRITE) != NO_ERROR ) { 1109 if( !bExtend ) 1110 break; 1111 1112 if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, 1113 PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && 1114 DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, 1115 PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { 1116 rc = SQLITE_NOMEM; 1117 break; 1118 } 1119 } 1120 1121 apRegion[pNode->nRegion++] = pvTemp; 1122 } 1123 1124 /* zero out remaining entries */ 1125 for( n = pNode->nRegion; n <= iRegion; n++ ) 1126 pNode->apRegion[n] = NULL; 1127 1128 /* Return this region (maybe zero) */ 1129 *pp = pNode->apRegion[iRegion]; 1130 } else { 1131 rc = SQLITE_NOMEM; 1132 } 1133 1134 /* Allow other processes to resize the shared memory */ 1135 os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); 1136 1137 } else { 1138 /* Region has been mapped previously */ 1139 *pp = pNode->apRegion[iRegion]; 1140 } 1141 1142 sqlite3_mutex_leave(pNode->mutex); 1143 } 1144 1145 ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", 1146 pFile->zFullPathCp, iRegion, szRegion, bExtend, rc)) 1147 1148 return rc; 1149} 1150 1151/* 1152** Close a connection to shared-memory. Delete the underlying 1153** storage if deleteFlag is true. 1154** 1155** If there is no shared memory associated with the connection then this 1156** routine is a harmless no-op. 1157*/ 1158static int os2ShmUnmap( 1159 sqlite3_file *id, /* The underlying database file */ 1160 int deleteFlag /* Delete shared-memory if true */ 1161){ 1162 os2File *pFile = (os2File*)id; 1163 os2ShmLink *pLink = pFile->pShmLink; 1164 1165 if( pLink ) { 1166 int nRef = -1; 1167 os2ShmLink **ppLink; 1168 os2ShmNode *pNode = pLink->pShmNode; 1169 1170 sqlite3_mutex_enter(pNode->mutex); 1171 1172 for( ppLink = &pNode->pFirst; 1173 *ppLink && *ppLink != pLink; 1174 ppLink = &(*ppLink)->pNext ) ; 1175 1176 assert(*ppLink); 1177 1178 if( *ppLink ) { 1179 *ppLink = pLink->pNext; 1180 nRef = --pNode->nRef; 1181 } else { 1182 ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", 1183 pNode->shmBaseName)) 1184 } 1185 1186 pFile->pShmLink = NULL; 1187 sqlite3_free(pLink); 1188 1189 sqlite3_mutex_leave(pNode->mutex); 1190 1191 if( nRef == 0 ) 1192 os2PurgeShmNodes( deleteFlag ); 1193 } 1194 1195 return SQLITE_OK; 1196} 1197 1198/* 1199** Change the lock state for a shared-memory segment. 1200** 1201** Note that the relationship between SHAREd and EXCLUSIVE locks is a little 1202** different here than in posix. In xShmLock(), one can go from unlocked 1203** to shared and back or from unlocked to exclusive and back. But one may 1204** not go from shared to exclusive or from exclusive to shared. 1205*/ 1206static int os2ShmLock( 1207 sqlite3_file *id, /* Database file holding the shared memory */ 1208 int ofst, /* First lock to acquire or release */ 1209 int n, /* Number of locks to acquire or release */ 1210 int flags /* What to do with the lock */ 1211){ 1212 u32 mask; /* Mask of locks to take or release */ 1213 int rc = SQLITE_OK; /* Result code */ 1214 os2File *pFile = (os2File*)id; 1215 os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */ 1216 os2ShmLink *pX; /* For looping over all siblings */ 1217 os2ShmNode *pShmNode = p->pShmNode; /* Our node */ 1218 1219 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); 1220 assert( n>=1 ); 1221 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) 1222 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) 1223 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) 1224 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); 1225 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); 1226 1227 mask = (u32)((1U<<(ofst+n)) - (1U<<ofst)); 1228 assert( n>1 || mask==(1<<ofst) ); 1229 1230 1231 sqlite3_mutex_enter(pShmNode->mutex); 1232 1233 if( flags & SQLITE_SHM_UNLOCK ){ 1234 u32 allMask = 0; /* Mask of locks held by siblings */ 1235 1236 /* See if any siblings hold this same lock */ 1237 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 1238 if( pX==p ) continue; 1239 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); 1240 allMask |= pX->sharedMask; 1241 } 1242 1243 /* Unlock the system-level locks */ 1244 if( (mask & allMask)==0 ){ 1245 rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n); 1246 }else{ 1247 rc = SQLITE_OK; 1248 } 1249 1250 /* Undo the local locks */ 1251 if( rc==SQLITE_OK ){ 1252 p->exclMask &= ~mask; 1253 p->sharedMask &= ~mask; 1254 } 1255 }else if( flags & SQLITE_SHM_SHARED ){ 1256 u32 allShared = 0; /* Union of locks held by connections other than "p" */ 1257 1258 /* Find out which shared locks are already held by sibling connections. 1259 ** If any sibling already holds an exclusive lock, go ahead and return 1260 ** SQLITE_BUSY. 1261 */ 1262 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 1263 if( (pX->exclMask & mask)!=0 ){ 1264 rc = SQLITE_BUSY; 1265 break; 1266 } 1267 allShared |= pX->sharedMask; 1268 } 1269 1270 /* Get shared locks at the system level, if necessary */ 1271 if( rc==SQLITE_OK ){ 1272 if( (allShared & mask)==0 ){ 1273 rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n); 1274 }else{ 1275 rc = SQLITE_OK; 1276 } 1277 } 1278 1279 /* Get the local shared locks */ 1280 if( rc==SQLITE_OK ){ 1281 p->sharedMask |= mask; 1282 } 1283 }else{ 1284 /* Make sure no sibling connections hold locks that will block this 1285 ** lock. If any do, return SQLITE_BUSY right away. 1286 */ 1287 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ 1288 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ 1289 rc = SQLITE_BUSY; 1290 break; 1291 } 1292 } 1293 1294 /* Get the exclusive locks at the system level. Then if successful 1295 ** also mark the local connection as being locked. 1296 */ 1297 if( rc==SQLITE_OK ){ 1298 rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n); 1299 if( rc==SQLITE_OK ){ 1300 assert( (p->sharedMask & mask)==0 ); 1301 p->exclMask |= mask; 1302 } 1303 } 1304 } 1305 1306 sqlite3_mutex_leave(pShmNode->mutex); 1307 1308 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", 1309 p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, 1310 rc ? "failed" : "ok")); 1311 1312 ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", 1313 ofst, n, flags, rc)) 1314 1315 return rc; 1316} 1317 1318/* 1319** Implement a memory barrier or memory fence on shared memory. 1320** 1321** All loads and stores begun before the barrier must complete before 1322** any load or store begun after the barrier. 1323*/ 1324static void os2ShmBarrier( 1325 sqlite3_file *id /* Database file holding the shared memory */ 1326){ 1327 UNUSED_PARAMETER(id); 1328 os2ShmEnterMutex(); 1329 os2ShmLeaveMutex(); 1330} 1331 1332#else 1333# define os2ShmMap 0 1334# define os2ShmLock 0 1335# define os2ShmBarrier 0 1336# define os2ShmUnmap 0 1337#endif /* #ifndef SQLITE_OMIT_WAL */ 1338 1339 1340/* 1341** This vector defines all the methods that can operate on an 1342** sqlite3_file for os2. 1343*/ 1344static const sqlite3_io_methods os2IoMethod = { 1345 2, /* iVersion */ 1346 os2Close, /* xClose */ 1347 os2Read, /* xRead */ 1348 os2Write, /* xWrite */ 1349 os2Truncate, /* xTruncate */ 1350 os2Sync, /* xSync */ 1351 os2FileSize, /* xFileSize */ 1352 os2Lock, /* xLock */ 1353 os2Unlock, /* xUnlock */ 1354 os2CheckReservedLock, /* xCheckReservedLock */ 1355 os2FileControl, /* xFileControl */ 1356 os2SectorSize, /* xSectorSize */ 1357 os2DeviceCharacteristics, /* xDeviceCharacteristics */ 1358 os2ShmMap, /* xShmMap */ 1359 os2ShmLock, /* xShmLock */ 1360 os2ShmBarrier, /* xShmBarrier */ 1361 os2ShmUnmap /* xShmUnmap */ 1362}; 1363 1364 1365/*************************************************************************** 1366** Here ends the I/O methods that form the sqlite3_io_methods object. 1367** 1368** The next block of code implements the VFS methods. 1369****************************************************************************/ 1370 1371/* 1372** Create a temporary file name in zBuf. zBuf must be big enough to 1373** hold at pVfs->mxPathname characters. 1374*/ 1375static int getTempname(int nBuf, char *zBuf ){ 1376 static const char zChars[] = 1377 "abcdefghijklmnopqrstuvwxyz" 1378 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1379 "0123456789"; 1380 int i, j; 1381 PSZ zTempPathCp; 1382 char zTempPath[CCHMAXPATH]; 1383 ULONG ulDriveNum, ulDriveMap; 1384 1385 /* It's odd to simulate an io-error here, but really this is just 1386 ** using the io-error infrastructure to test that SQLite handles this 1387 ** function failing. 1388 */ 1389 SimulateIOError( return SQLITE_IOERR ); 1390 1391 if( sqlite3_temp_directory ) { 1392 sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory); 1393 } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR || 1394 DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR || 1395 DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) { 1396 char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp ); 1397 sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF); 1398 free( zTempPathUTF ); 1399 } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) { 1400 zTempPath[0] = (char)('A' + ulDriveNum - 1); 1401 zTempPath[1] = ':'; 1402 zTempPath[2] = '\0'; 1403 } else { 1404 zTempPath[0] = '\0'; 1405 } 1406 1407 /* Strip off a trailing slashes or backslashes, otherwise we would get * 1408 * multiple (back)slashes which causes DosOpen() to fail. * 1409 * Trailing spaces are not allowed, either. */ 1410 j = sqlite3Strlen30(zTempPath); 1411 while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || 1412 zTempPath[j-1] == ' ' ) ){ 1413 j--; 1414 } 1415 zTempPath[j] = '\0'; 1416 1417 /* We use 20 bytes to randomize the name */ 1418 sqlite3_snprintf(nBuf-22, zBuf, 1419 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); 1420 j = sqlite3Strlen30(zBuf); 1421 sqlite3_randomness( 20, &zBuf[j] ); 1422 for( i = 0; i < 20; i++, j++ ){ 1423 zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 1424 } 1425 zBuf[j] = 0; 1426 1427 OSTRACE(( "TEMP FILENAME: %s\n", zBuf )); 1428 return SQLITE_OK; 1429} 1430 1431 1432/* 1433** Turn a relative pathname into a full pathname. Write the full 1434** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname 1435** bytes in size. 1436*/ 1437static int os2FullPathname( 1438 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 1439 const char *zRelative, /* Possibly relative input path */ 1440 int nFull, /* Size of output buffer in bytes */ 1441 char *zFull /* Output buffer */ 1442){ 1443 char *zRelativeCp = convertUtf8PathToCp( zRelative ); 1444 char zFullCp[CCHMAXPATH] = "\0"; 1445 char *zFullUTF; 1446 APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, 1447 zFullCp, CCHMAXPATH ); 1448 free( zRelativeCp ); 1449 zFullUTF = convertCpPathToUtf8( zFullCp ); 1450 sqlite3_snprintf( nFull, zFull, zFullUTF ); 1451 free( zFullUTF ); 1452 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; 1453} 1454 1455 1456/* 1457** Open a file. 1458*/ 1459static int os2Open( 1460 sqlite3_vfs *pVfs, /* Not used */ 1461 const char *zName, /* Name of the file (UTF-8) */ 1462 sqlite3_file *id, /* Write the SQLite file handle here */ 1463 int flags, /* Open mode flags */ 1464 int *pOutFlags /* Status return flags */ 1465){ 1466 HFILE h; 1467 ULONG ulOpenFlags = 0; 1468 ULONG ulOpenMode = 0; 1469 ULONG ulAction = 0; 1470 ULONG rc; 1471 os2File *pFile = (os2File*)id; 1472 const char *zUtf8Name = zName; 1473 char *zNameCp; 1474 char zTmpname[CCHMAXPATH]; 1475 1476 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); 1477 int isCreate = (flags & SQLITE_OPEN_CREATE); 1478 int isReadWrite = (flags & SQLITE_OPEN_READWRITE); 1479#ifndef NDEBUG 1480 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); 1481 int isReadonly = (flags & SQLITE_OPEN_READONLY); 1482 int eType = (flags & 0xFFFFFF00); 1483 int isOpenJournal = (isCreate && ( 1484 eType==SQLITE_OPEN_MASTER_JOURNAL 1485 || eType==SQLITE_OPEN_MAIN_JOURNAL 1486 || eType==SQLITE_OPEN_WAL 1487 )); 1488#endif 1489 1490 UNUSED_PARAMETER(pVfs); 1491 assert( id!=0 ); 1492 1493 /* Check the following statements are true: 1494 ** 1495 ** (a) Exactly one of the READWRITE and READONLY flags must be set, and 1496 ** (b) if CREATE is set, then READWRITE must also be set, and 1497 ** (c) if EXCLUSIVE is set, then CREATE must also be set. 1498 ** (d) if DELETEONCLOSE is set, then CREATE must also be set. 1499 */ 1500 assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); 1501 assert(isCreate==0 || isReadWrite); 1502 assert(isExclusive==0 || isCreate); 1503 assert(isDelete==0 || isCreate); 1504 1505 /* The main DB, main journal, WAL file and master journal are never 1506 ** automatically deleted. Nor are they ever temporary files. */ 1507 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); 1508 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); 1509 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); 1510 assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); 1511 1512 /* Assert that the upper layer has set one of the "file-type" flags. */ 1513 assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB 1514 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 1515 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL 1516 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL 1517 ); 1518 1519 memset( pFile, 0, sizeof(*pFile) ); 1520 pFile->h = (HFILE)-1; 1521 1522 /* If the second argument to this function is NULL, generate a 1523 ** temporary file name to use 1524 */ 1525 if( !zUtf8Name ){ 1526 assert(isDelete && !isOpenJournal); 1527 rc = getTempname(CCHMAXPATH, zTmpname); 1528 if( rc!=SQLITE_OK ){ 1529 return rc; 1530 } 1531 zUtf8Name = zTmpname; 1532 } 1533 1534 if( isReadWrite ){ 1535 ulOpenMode |= OPEN_ACCESS_READWRITE; 1536 }else{ 1537 ulOpenMode |= OPEN_ACCESS_READONLY; 1538 } 1539 1540 /* Open in random access mode for possibly better speed. Allow full 1541 ** sharing because file locks will provide exclusive access when needed. 1542 ** The handle should not be inherited by child processes and we don't 1543 ** want popups from the critical error handler. 1544 */ 1545 ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | 1546 OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR; 1547 1548 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 1549 ** created. SQLite doesn't use it to indicate "exclusive access" 1550 ** as it is usually understood. 1551 */ 1552 if( isExclusive ){ 1553 /* Creates a new file, only if it does not already exist. */ 1554 /* If the file exists, it fails. */ 1555 ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; 1556 }else if( isCreate ){ 1557 /* Open existing file, or create if it doesn't exist */ 1558 ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; 1559 }else{ 1560 /* Opens a file, only if it exists. */ 1561 ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; 1562 } 1563 1564 zNameCp = convertUtf8PathToCp( zUtf8Name ); 1565 rc = DosOpen( (PSZ)zNameCp, 1566 &h, 1567 &ulAction, 1568 0L, 1569 FILE_NORMAL, 1570 ulOpenFlags, 1571 ulOpenMode, 1572 (PEAOP2)NULL ); 1573 free( zNameCp ); 1574 1575 if( rc != NO_ERROR ){ 1576 OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", 1577 rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); 1578 1579 if( isReadWrite ){ 1580 return os2Open( pVfs, zName, id, 1581 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), 1582 pOutFlags ); 1583 }else{ 1584 return SQLITE_CANTOPEN; 1585 } 1586 } 1587 1588 if( pOutFlags ){ 1589 *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; 1590 } 1591 1592 os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname ); 1593 pFile->zFullPathCp = convertUtf8PathToCp( zTmpname ); 1594 pFile->pMethod = &os2IoMethod; 1595 pFile->flags = flags; 1596 pFile->h = h; 1597 1598 OpenCounter(+1); 1599 OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); 1600 return SQLITE_OK; 1601} 1602 1603/* 1604** Delete the named file. 1605*/ 1606static int os2Delete( 1607 sqlite3_vfs *pVfs, /* Not used on os2 */ 1608 const char *zFilename, /* Name of file to delete */ 1609 int syncDir /* Not used on os2 */ 1610){ 1611 APIRET rc; 1612 char *zFilenameCp; 1613 SimulateIOError( return SQLITE_IOERR_DELETE ); 1614 zFilenameCp = convertUtf8PathToCp( zFilename ); 1615 rc = DosDelete( (PSZ)zFilenameCp ); 1616 free( zFilenameCp ); 1617 OSTRACE(( "DELETE \"%s\"\n", zFilename )); 1618 return (rc == NO_ERROR || 1619 rc == ERROR_FILE_NOT_FOUND || 1620 rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; 1621} 1622 1623/* 1624** Check the existance and status of a file. 1625*/ 1626static int os2Access( 1627 sqlite3_vfs *pVfs, /* Not used on os2 */ 1628 const char *zFilename, /* Name of file to check */ 1629 int flags, /* Type of test to make on this file */ 1630 int *pOut /* Write results here */ 1631){ 1632 APIRET rc; 1633 FILESTATUS3 fsts3ConfigInfo; 1634 char *zFilenameCp; 1635 1636 UNUSED_PARAMETER(pVfs); 1637 SimulateIOError( return SQLITE_IOERR_ACCESS; ); 1638 1639 zFilenameCp = convertUtf8PathToCp( zFilename ); 1640 rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, 1641 &fsts3ConfigInfo, sizeof(FILESTATUS3) ); 1642 free( zFilenameCp ); 1643 OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", 1644 fsts3ConfigInfo.attrFile, flags, rc )); 1645 1646 switch( flags ){ 1647 case SQLITE_ACCESS_EXISTS: 1648 /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file 1649 ** as if it does not exist. 1650 */ 1651 if( fsts3ConfigInfo.cbFile == 0 ) 1652 rc = ERROR_FILE_NOT_FOUND; 1653 break; 1654 case SQLITE_ACCESS_READ: 1655 break; 1656 case SQLITE_ACCESS_READWRITE: 1657 if( fsts3ConfigInfo.attrFile & FILE_READONLY ) 1658 rc = ERROR_ACCESS_DENIED; 1659 break; 1660 default: 1661 rc = ERROR_FILE_NOT_FOUND; 1662 assert( !"Invalid flags argument" ); 1663 } 1664 1665 *pOut = (rc == NO_ERROR); 1666 OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut )); 1667 1668 return SQLITE_OK; 1669} 1670 1671 1672#ifndef SQLITE_OMIT_LOAD_EXTENSION 1673/* 1674** Interfaces for opening a shared library, finding entry points 1675** within the shared library, and closing the shared library. 1676*/ 1677/* 1678** Interfaces for opening a shared library, finding entry points 1679** within the shared library, and closing the shared library. 1680*/ 1681static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 1682 HMODULE hmod; 1683 APIRET rc; 1684 char *zFilenameCp = convertUtf8PathToCp(zFilename); 1685 rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod); 1686 free(zFilenameCp); 1687 return rc != NO_ERROR ? 0 : (void*)hmod; 1688} 1689/* 1690** A no-op since the error code is returned on the DosLoadModule call. 1691** os2Dlopen returns zero if DosLoadModule is not successful. 1692*/ 1693static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 1694/* no-op */ 1695} 1696static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ 1697 PFN pfn; 1698 APIRET rc; 1699 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn); 1700 if( rc != NO_ERROR ){ 1701 /* if the symbol itself was not found, search again for the same 1702 * symbol with an extra underscore, that might be needed depending 1703 * on the calling convention */ 1704 char _zSymbol[256] = "_"; 1705 strncat(_zSymbol, zSymbol, 254); 1706 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn); 1707 } 1708 return rc != NO_ERROR ? 0 : (void(*)(void))pfn; 1709} 1710static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ 1711 DosFreeModule((HMODULE)pHandle); 1712} 1713#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 1714 #define os2DlOpen 0 1715 #define os2DlError 0 1716 #define os2DlSym 0 1717 #define os2DlClose 0 1718#endif 1719 1720 1721/* 1722** Write up to nBuf bytes of randomness into zBuf. 1723*/ 1724static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ 1725 int n = 0; 1726#if defined(SQLITE_TEST) 1727 n = nBuf; 1728 memset(zBuf, 0, nBuf); 1729#else 1730 int i; 1731 PPIB ppib; 1732 PTIB ptib; 1733 DATETIME dt; 1734 static unsigned c = 0; 1735 /* Ordered by variation probability */ 1736 static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW, 1737 QSV_MAXPRMEM, QSV_MAXSHMEM, 1738 QSV_TOTAVAILMEM, QSV_TOTRESMEM }; 1739 1740 /* 8 bytes; timezone and weekday don't increase the randomness much */ 1741 if( (int)sizeof(dt)-3 <= nBuf - n ){ 1742 c += 0x0100; 1743 DosGetDateTime(&dt); 1744 dt.year = (USHORT)((dt.year - 1900) | c); 1745 memcpy(&zBuf[n], &dt, sizeof(dt)-3); 1746 n += sizeof(dt)-3; 1747 } 1748 1749 /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */ 1750 if( (int)sizeof(ULONG) <= nBuf - n ){ 1751 DosGetInfoBlocks(&ptib, &ppib); 1752 *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid, 1753 ptib->tib_ptib2->tib2_ultid); 1754 n += sizeof(ULONG); 1755 } 1756 1757 /* Up to 6 * 4 bytes; variables depend on the system state */ 1758 for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){ 1759 DosQuerySysInfo(svIdx[i], svIdx[i], 1760 (PULONG)&zBuf[n], sizeof(ULONG)); 1761 n += sizeof(ULONG); 1762 } 1763#endif 1764 1765 return n; 1766} 1767 1768/* 1769** Sleep for a little while. Return the amount of time slept. 1770** The argument is the number of microseconds we want to sleep. 1771** The return value is the number of microseconds of sleep actually 1772** requested from the underlying operating system, a number which 1773** might be greater than or equal to the argument, but not less 1774** than the argument. 1775*/ 1776static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){ 1777 DosSleep( (microsec/1000) ); 1778 return microsec; 1779} 1780 1781/* 1782** The following variable, if set to a non-zero value, becomes the result 1783** returned from sqlite3OsCurrentTime(). This is used for testing. 1784*/ 1785#ifdef SQLITE_TEST 1786int sqlite3_current_time = 0; 1787#endif 1788 1789/* 1790** Find the current time (in Universal Coordinated Time). Write into *piNow 1791** the current time and date as a Julian Day number times 86_400_000. In 1792** other words, write into *piNow the number of milliseconds since the Julian 1793** epoch of noon in Greenwich on November 24, 4714 B.C according to the 1794** proleptic Gregorian calendar. 1795** 1796** On success, return 0. Return 1 if the time and date cannot be found. 1797*/ 1798static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ 1799#ifdef SQLITE_TEST 1800 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; 1801#endif 1802 int year, month, datepart, timepart; 1803 1804 DATETIME dt; 1805 DosGetDateTime( &dt ); 1806 1807 year = dt.year; 1808 month = dt.month; 1809 1810 /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html 1811 ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c 1812 ** Calculate the Julian days 1813 */ 1814 datepart = (int)dt.day - 32076 + 1815 1461*(year + 4800 + (month - 14)/12)/4 + 1816 367*(month - 2 - (month - 14)/12*12)/12 - 1817 3*((year + 4900 + (month - 14)/12)/100)/4; 1818 1819 /* Time in milliseconds, hours to noon added */ 1820 timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 + 1821 ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000; 1822 1823 *piNow = (sqlite3_int64)datepart*86400*1000 + timepart; 1824 1825#ifdef SQLITE_TEST 1826 if( sqlite3_current_time ){ 1827 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; 1828 } 1829#endif 1830 1831 UNUSED_PARAMETER(pVfs); 1832 return 0; 1833} 1834 1835/* 1836** Find the current time (in Universal Coordinated Time). Write the 1837** current time and date as a Julian Day number into *prNow and 1838** return 0. Return 1 if the time and date cannot be found. 1839*/ 1840static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ 1841 int rc; 1842 sqlite3_int64 i; 1843 rc = os2CurrentTimeInt64(pVfs, &i); 1844 if( !rc ){ 1845 *prNow = i/86400000.0; 1846 } 1847 return rc; 1848} 1849 1850/* 1851** The idea is that this function works like a combination of 1852** GetLastError() and FormatMessage() on windows (or errno and 1853** strerror_r() on unix). After an error is returned by an OS 1854** function, SQLite calls this function with zBuf pointing to 1855** a buffer of nBuf bytes. The OS layer should populate the 1856** buffer with a nul-terminated UTF-8 encoded error message 1857** describing the last IO error to have occurred within the calling 1858** thread. 1859** 1860** If the error message is too large for the supplied buffer, 1861** it should be truncated. The return value of xGetLastError 1862** is zero if the error message fits in the buffer, or non-zero 1863** otherwise (if the message was truncated). If non-zero is returned, 1864** then it is not necessary to include the nul-terminator character 1865** in the output buffer. 1866** 1867** Not supplying an error message will have no adverse effect 1868** on SQLite. It is fine to have an implementation that never 1869** returns an error message: 1870** 1871** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1872** assert(zBuf[0]=='\0'); 1873** return 0; 1874** } 1875** 1876** However if an error message is supplied, it will be incorporated 1877** by sqlite into the error message available to the user using 1878** sqlite3_errmsg(), possibly making IO errors easier to debug. 1879*/ 1880static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1881 assert(zBuf[0]=='\0'); 1882 return 0; 1883} 1884 1885/* 1886** Initialize and deinitialize the operating system interface. 1887*/ 1888int sqlite3_os_init(void){ 1889 static sqlite3_vfs os2Vfs = { 1890 3, /* iVersion */ 1891 sizeof(os2File), /* szOsFile */ 1892 CCHMAXPATH, /* mxPathname */ 1893 0, /* pNext */ 1894 "os2", /* zName */ 1895 0, /* pAppData */ 1896 1897 os2Open, /* xOpen */ 1898 os2Delete, /* xDelete */ 1899 os2Access, /* xAccess */ 1900 os2FullPathname, /* xFullPathname */ 1901 os2DlOpen, /* xDlOpen */ 1902 os2DlError, /* xDlError */ 1903 os2DlSym, /* xDlSym */ 1904 os2DlClose, /* xDlClose */ 1905 os2Randomness, /* xRandomness */ 1906 os2Sleep, /* xSleep */ 1907 os2CurrentTime, /* xCurrentTime */ 1908 os2GetLastError, /* xGetLastError */ 1909 os2CurrentTimeInt64, /* xCurrentTimeInt64 */ 1910 0, /* xSetSystemCall */ 1911 0, /* xGetSystemCall */ 1912 0 /* xNextSystemCall */ 1913 }; 1914 sqlite3_vfs_register(&os2Vfs, 1); 1915 initUconvObjects(); 1916/* sqlite3OSTrace = 1; */ 1917 return SQLITE_OK; 1918} 1919int sqlite3_os_end(void){ 1920 freeUconvObjects(); 1921 return SQLITE_OK; 1922} 1923 1924#endif /* SQLITE_OS_OS2 */ 1925