Annotation of embedaddon/sqlite3/src/os_os2.c, revision 1.1.1.1

1.1       misho       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 */
                     59: typedef struct os2File os2File;         /* The file structure */
                     60: typedef struct os2ShmNode os2ShmNode;   /* A shared descritive memory node */
                     61: typedef 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: */
                     67: struct 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: */
                     95: static 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: */
                    122: static 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: */
                    153: static 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: */
                    185: static 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: */
                    210: int sqlite3_sync_count = 0;
                    211: int sqlite3_fullsync_count = 0;
                    212: #endif
                    213: 
                    214: /*
                    215: ** Make sure all writes to a particular file are committed to disk.
                    216: */
                    217: static 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: */
                    240: static 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: */
                    258: static 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: */
                    276: static 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: */
                    317: static 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: */
                    454: static 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: */
                    500: static 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: */
                    556: static 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: */
                    592: static 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: */
                    600: static 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: */
                    609: static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
                    610: static 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: */
                    615: static 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: */
                    625: static 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: */
                    640: static 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: */
                    669: char *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
                    700: static 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: */
                    724: static void os2ShmEnterMutex(void){
                    725:   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
                    726: }
                    727: static void os2ShmLeaveMutex(void){
                    728:   sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
                    729: }
                    730: #ifdef SQLITE_DEBUG
                    731: static int os2ShmMutexHeld(void) {
                    732:   return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
                    733: }
                    734: int 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: */
                    764: struct 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: */
                    794: struct 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: */
                    810: static 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 */
                    830: static 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: */
                    881: static 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: */
                    986: static 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: */
                   1066: static 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: */
                   1158: static 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: */
                   1206: static 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: */
                   1324: static 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: */
                   1344: static 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: */
                   1375: static 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: */
                   1437: static 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: */
                   1459: static 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: */
                   1606: static 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: */
                   1626: static 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: */
                   1681: static 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: */
                   1693: static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
                   1694: /* no-op */
                   1695: }
                   1696: static 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: }
                   1710: static 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: */
                   1724: static 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: */
                   1776: static 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
                   1786: int 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: */
                   1798: static 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: */
                   1840: static 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: */
                   1880: static 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: */
                   1888: int 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: }
                   1919: int sqlite3_os_end(void){
                   1920:   freeUconvObjects();
                   1921:   return SQLITE_OK;
                   1922: }
                   1923: 
                   1924: #endif /* SQLITE_OS_OS2 */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>