Annotation of embedaddon/php/ext/sqlite/libsqlite/src/os.c, revision 1.1.1.1

1.1       misho       1: /*
                      2: ** 2001 September 16
                      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 particular operating
                     14: ** systems.  The purpose of this file is to provide a uniform abstraction
                     15: ** on which the rest of SQLite can operate.
                     16: */
                     17: #include "os.h"          /* Must be first to enable large file support */
                     18: #include "sqliteInt.h"
                     19: 
                     20: #if OS_UNIX
                     21: # include <time.h>
                     22: # include <errno.h>
                     23: # include <unistd.h>
                     24: # ifndef O_LARGEFILE
                     25: #  define O_LARGEFILE 0
                     26: # endif
                     27: # ifdef SQLITE_DISABLE_LFS
                     28: #  undef O_LARGEFILE
                     29: #  define O_LARGEFILE 0
                     30: # endif
                     31: # ifndef O_NOFOLLOW
                     32: #  define O_NOFOLLOW 0
                     33: # endif
                     34: # ifndef O_BINARY
                     35: #  define O_BINARY 0
                     36: # endif
                     37: #endif
                     38: 
                     39: 
                     40: #if OS_WIN
                     41: # include <winbase.h>
                     42: #endif
                     43: 
                     44: #if OS_MAC
                     45: # include <extras.h>
                     46: # include <path2fss.h>
                     47: # include <TextUtils.h>
                     48: # include <FinderRegistry.h>
                     49: # include <Folders.h>
                     50: # include <Timer.h>
                     51: # include <OSUtils.h>
                     52: #endif
                     53: 
                     54: /*
                     55: ** The DJGPP compiler environment looks mostly like Unix, but it
                     56: ** lacks the fcntl() system call.  So redefine fcntl() to be something
                     57: ** that always succeeds.  This means that locking does not occur under
                     58: ** DJGPP.  But its DOS - what did you expect?
                     59: */
                     60: #ifdef __DJGPP__
                     61: # define fcntl(A,B,C) 0
                     62: #endif
                     63: 
                     64: /*
                     65: ** Macros used to determine whether or not to use threads.  The
                     66: ** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
                     67: ** Posix threads and SQLITE_W32_THREADS is defined if we are
                     68: ** synchronizing using Win32 threads.
                     69: */
                     70: #if OS_UNIX && defined(THREADSAFE) && THREADSAFE
                     71: # include <pthread.h>
                     72: # define SQLITE_UNIX_THREADS 1
                     73: #endif
                     74: #if OS_WIN && defined(THREADSAFE) && THREADSAFE
                     75: # define SQLITE_W32_THREADS 1
                     76: #endif
                     77: #if OS_MAC && defined(THREADSAFE) && THREADSAFE
                     78: # include <Multiprocessing.h>
                     79: # define SQLITE_MACOS_MULTITASKING 1
                     80: #endif
                     81: 
                     82: /*
                     83: ** Macros for performance tracing.  Normally turned off
                     84: */
                     85: #if 0
                     86: static int last_page = 0;
                     87: __inline__ unsigned long long int hwtime(void){
                     88:   unsigned long long int x;
                     89:   __asm__("rdtsc\n\t"
                     90:           "mov %%edx, %%ecx\n\t"
                     91:           :"=A" (x));
                     92:   return x;
                     93: }
                     94: static unsigned long long int g_start;
                     95: static unsigned int elapse;
                     96: #define TIMER_START       g_start=hwtime()
                     97: #define TIMER_END         elapse=hwtime()-g_start
                     98: #define SEEK(X)           last_page=(X)
                     99: #define TRACE1(X)         fprintf(stderr,X)
                    100: #define TRACE2(X,Y)       fprintf(stderr,X,Y)
                    101: #define TRACE3(X,Y,Z)     fprintf(stderr,X,Y,Z)
                    102: #define TRACE4(X,Y,Z,A)   fprintf(stderr,X,Y,Z,A)
                    103: #define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
                    104: #else
                    105: #define TIMER_START
                    106: #define TIMER_END
                    107: #define SEEK(X)
                    108: #define TRACE1(X)
                    109: #define TRACE2(X,Y)
                    110: #define TRACE3(X,Y,Z)
                    111: #define TRACE4(X,Y,Z,A)
                    112: #define TRACE5(X,Y,Z,A,B)
                    113: #endif
                    114: 
                    115: 
                    116: #if OS_UNIX
                    117: /*
                    118: ** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
                    119: ** section 6.5.2.2 lines 483 through 490 specify that when a process
                    120: ** sets or clears a lock, that operation overrides any prior locks set
                    121: ** by the same process.  It does not explicitly say so, but this implies
                    122: ** that it overrides locks set by the same process using a different
                    123: ** file descriptor.  Consider this test case:
                    124: **
                    125: **       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
                    126: **       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
                    127: **
                    128: ** Suppose ./file1 and ./file2 are really the same file (because
                    129: ** one is a hard or symbolic link to the other) then if you set
                    130: ** an exclusive lock on fd1, then try to get an exclusive lock
                    131: ** on fd2, it works.  I would have expected the second lock to
                    132: ** fail since there was already a lock on the file due to fd1.
                    133: ** But not so.  Since both locks came from the same process, the
                    134: ** second overrides the first, even though they were on different
                    135: ** file descriptors opened on different file names.
                    136: **
                    137: ** Bummer.  If you ask me, this is broken.  Badly broken.  It means
                    138: ** that we cannot use POSIX locks to synchronize file access among
                    139: ** competing threads of the same process.  POSIX locks will work fine
                    140: ** to synchronize access for threads in separate processes, but not
                    141: ** threads within the same process.
                    142: **
                    143: ** To work around the problem, SQLite has to manage file locks internally
                    144: ** on its own.  Whenever a new database is opened, we have to find the
                    145: ** specific inode of the database file (the inode is determined by the
                    146: ** st_dev and st_ino fields of the stat structure that fstat() fills in)
                    147: ** and check for locks already existing on that inode.  When locks are
                    148: ** created or removed, we have to look at our own internal record of the
                    149: ** locks to see if another thread has previously set a lock on that same
                    150: ** inode.
                    151: **
                    152: ** The OsFile structure for POSIX is no longer just an integer file
                    153: ** descriptor.  It is now a structure that holds the integer file
                    154: ** descriptor and a pointer to a structure that describes the internal
                    155: ** locks on the corresponding inode.  There is one locking structure
                    156: ** per inode, so if the same inode is opened twice, both OsFile structures
                    157: ** point to the same locking structure.  The locking structure keeps
                    158: ** a reference count (so we will know when to delete it) and a "cnt"
                    159: ** field that tells us its internal lock status.  cnt==0 means the
                    160: ** file is unlocked.  cnt==-1 means the file has an exclusive lock.
                    161: ** cnt>0 means there are cnt shared locks on the file.
                    162: **
                    163: ** Any attempt to lock or unlock a file first checks the locking
                    164: ** structure.  The fcntl() system call is only invoked to set a 
                    165: ** POSIX lock if the internal lock structure transitions between
                    166: ** a locked and an unlocked state.
                    167: **
                    168: ** 2004-Jan-11:
                    169: ** More recent discoveries about POSIX advisory locks.  (The more
                    170: ** I discover, the more I realize the a POSIX advisory locks are
                    171: ** an abomination.)
                    172: **
                    173: ** If you close a file descriptor that points to a file that has locks,
                    174: ** all locks on that file that are owned by the current process are
                    175: ** released.  To work around this problem, each OsFile structure contains
                    176: ** a pointer to an openCnt structure.  There is one openCnt structure
                    177: ** per open inode, which means that multiple OsFiles can point to a single
                    178: ** openCnt.  When an attempt is made to close an OsFile, if there are
                    179: ** other OsFiles open on the same inode that are holding locks, the call
                    180: ** to close() the file descriptor is deferred until all of the locks clear.
                    181: ** The openCnt structure keeps a list of file descriptors that need to
                    182: ** be closed and that list is walked (and cleared) when the last lock
                    183: ** clears.
                    184: **
                    185: ** First, under Linux threads, because each thread has a separate
                    186: ** process ID, lock operations in one thread do not override locks
                    187: ** to the same file in other threads.  Linux threads behave like
                    188: ** separate processes in this respect.  But, if you close a file
                    189: ** descriptor in linux threads, all locks are cleared, even locks
                    190: ** on other threads and even though the other threads have different
                    191: ** process IDs.  Linux threads is inconsistent in this respect.
                    192: ** (I'm beginning to think that linux threads is an abomination too.)
                    193: ** The consequence of this all is that the hash table for the lockInfo
                    194: ** structure has to include the process id as part of its key because
                    195: ** locks in different threads are treated as distinct.  But the 
                    196: ** openCnt structure should not include the process id in its
                    197: ** key because close() clears lock on all threads, not just the current
                    198: ** thread.  Were it not for this goofiness in linux threads, we could
                    199: ** combine the lockInfo and openCnt structures into a single structure.
                    200: */
                    201: 
                    202: /*
                    203: ** An instance of the following structure serves as the key used
                    204: ** to locate a particular lockInfo structure given its inode.  Note
                    205: ** that we have to include the process ID as part of the key.  On some
                    206: ** threading implementations (ex: linux), each thread has a separate
                    207: ** process ID.
                    208: */
                    209: struct lockKey {
                    210:   dev_t dev;   /* Device number */
                    211:   ino_t ino;   /* Inode number */
                    212:   pid_t pid;   /* Process ID */
                    213: };
                    214: 
                    215: /*
                    216: ** An instance of the following structure is allocated for each open
                    217: ** inode on each thread with a different process ID.  (Threads have
                    218: ** different process IDs on linux, but not on most other unixes.)
                    219: **
                    220: ** A single inode can have multiple file descriptors, so each OsFile
                    221: ** structure contains a pointer to an instance of this object and this
                    222: ** object keeps a count of the number of OsFiles pointing to it.
                    223: */
                    224: struct lockInfo {
                    225:   struct lockKey key;  /* The lookup key */
                    226:   int cnt;             /* 0: unlocked.  -1: write lock.  1...: read lock. */
                    227:   int nRef;            /* Number of pointers to this structure */
                    228: };
                    229: 
                    230: /*
                    231: ** An instance of the following structure serves as the key used
                    232: ** to locate a particular openCnt structure given its inode.  This
                    233: ** is the same as the lockKey except that the process ID is omitted.
                    234: */
                    235: struct openKey {
                    236:   dev_t dev;   /* Device number */
                    237:   ino_t ino;   /* Inode number */
                    238: };
                    239: 
                    240: /*
                    241: ** An instance of the following structure is allocated for each open
                    242: ** inode.  This structure keeps track of the number of locks on that
                    243: ** inode.  If a close is attempted against an inode that is holding
                    244: ** locks, the close is deferred until all locks clear by adding the
                    245: ** file descriptor to be closed to the pending list.
                    246: */
                    247: struct openCnt {
                    248:   struct openKey key;   /* The lookup key */
                    249:   int nRef;             /* Number of pointers to this structure */
                    250:   int nLock;            /* Number of outstanding locks */
                    251:   int nPending;         /* Number of pending close() operations */
                    252:   int *aPending;        /* Malloced space holding fd's awaiting a close() */
                    253: };
                    254: 
                    255: /* 
                    256: ** These hash table maps inodes and process IDs into lockInfo and openCnt
                    257: ** structures.  Access to these hash tables must be protected by a mutex.
                    258: */
                    259: static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
                    260: static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
                    261: 
                    262: /*
                    263: ** Release a lockInfo structure previously allocated by findLockInfo().
                    264: */
                    265: static void releaseLockInfo(struct lockInfo *pLock){
                    266:   pLock->nRef--;
                    267:   if( pLock->nRef==0 ){
                    268:     sqliteHashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
                    269:     sqliteFree(pLock);
                    270:   }
                    271: }
                    272: 
                    273: /*
                    274: ** Release a openCnt structure previously allocated by findLockInfo().
                    275: */
                    276: static void releaseOpenCnt(struct openCnt *pOpen){
                    277:   pOpen->nRef--;
                    278:   if( pOpen->nRef==0 ){
                    279:     sqliteHashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
                    280:     sqliteFree(pOpen->aPending);
                    281:     sqliteFree(pOpen);
                    282:   }
                    283: }
                    284: 
                    285: /*
                    286: ** Given a file descriptor, locate lockInfo and openCnt structures that
                    287: ** describes that file descriptor.  Create a new ones if necessary.  The
                    288: ** return values might be unset if an error occurs.
                    289: **
                    290: ** Return the number of errors.
                    291: */
                    292: int findLockInfo(
                    293:   int fd,                      /* The file descriptor used in the key */
                    294:   struct lockInfo **ppLock,    /* Return the lockInfo structure here */
                    295:   struct openCnt **ppOpen   /* Return the openCnt structure here */
                    296: ){
                    297:   int rc;
                    298:   struct lockKey key1;
                    299:   struct openKey key2;
                    300:   struct stat statbuf;
                    301:   struct lockInfo *pLock;
                    302:   struct openCnt *pOpen;
                    303:   rc = fstat(fd, &statbuf);
                    304:   if( rc!=0 ) return 1;
                    305:   memset(&key1, 0, sizeof(key1));
                    306:   key1.dev = statbuf.st_dev;
                    307:   key1.ino = statbuf.st_ino;
                    308:   key1.pid = getpid();
                    309:   memset(&key2, 0, sizeof(key2));
                    310:   key2.dev = statbuf.st_dev;
                    311:   key2.ino = statbuf.st_ino;
                    312:   pLock = (struct lockInfo*)sqliteHashFind(&lockHash, &key1, sizeof(key1));
                    313:   if( pLock==0 ){
                    314:     struct lockInfo *pOld;
                    315:     pLock = sqliteMallocRaw( sizeof(*pLock) );
                    316:     if( pLock==0 ) return 1;
                    317:     pLock->key = key1;
                    318:     pLock->nRef = 1;
                    319:     pLock->cnt = 0;
                    320:     pOld = sqliteHashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
                    321:     if( pOld!=0 ){
                    322:       assert( pOld==pLock );
                    323:       sqliteFree(pLock);
                    324:       return 1;
                    325:     }
                    326:   }else{
                    327:     pLock->nRef++;
                    328:   }
                    329:   *ppLock = pLock;
                    330:   pOpen = (struct openCnt*)sqliteHashFind(&openHash, &key2, sizeof(key2));
                    331:   if( pOpen==0 ){
                    332:     struct openCnt *pOld;
                    333:     pOpen = sqliteMallocRaw( sizeof(*pOpen) );
                    334:     if( pOpen==0 ){
                    335:       releaseLockInfo(pLock);
                    336:       return 1;
                    337:     }
                    338:     pOpen->key = key2;
                    339:     pOpen->nRef = 1;
                    340:     pOpen->nLock = 0;
                    341:     pOpen->nPending = 0;
                    342:     pOpen->aPending = 0;
                    343:     pOld = sqliteHashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
                    344:     if( pOld!=0 ){
                    345:       assert( pOld==pOpen );
                    346:       sqliteFree(pOpen);
                    347:       releaseLockInfo(pLock);
                    348:       return 1;
                    349:     }
                    350:   }else{
                    351:     pOpen->nRef++;
                    352:   }
                    353:   *ppOpen = pOpen;
                    354:   return 0;
                    355: }
                    356: 
                    357: #endif  /** POSIX advisory lock work-around **/
                    358: 
                    359: /*
                    360: ** If we compile with the SQLITE_TEST macro set, then the following block
                    361: ** of code will give us the ability to simulate a disk I/O error.  This
                    362: ** is used for testing the I/O recovery logic.
                    363: */
                    364: #ifdef SQLITE_TEST
                    365: int sqlite_io_error_pending = 0;
                    366: #define SimulateIOError(A)  \
                    367:    if( sqlite_io_error_pending ) \
                    368:      if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; }
                    369: static void local_ioerr(){
                    370:   sqlite_io_error_pending = 0;  /* Really just a place to set a breakpoint */
                    371: }
                    372: #else
                    373: #define SimulateIOError(A)
                    374: #endif
                    375: 
                    376: /*
                    377: ** When testing, keep a count of the number of open files.
                    378: */
                    379: #ifdef SQLITE_TEST
                    380: int sqlite_open_file_count = 0;
                    381: #define OpenCounter(X)  sqlite_open_file_count+=(X)
                    382: #else
                    383: #define OpenCounter(X)
                    384: #endif
                    385: 
                    386: 
                    387: /*
                    388: ** Delete the named file
                    389: */
                    390: int sqliteOsDelete(const char *zFilename){
                    391: #if OS_UNIX
                    392:   unlink(zFilename);
                    393: #endif
                    394: #if OS_WIN
                    395:   DeleteFile(zFilename);
                    396: #endif
                    397: #if OS_MAC
                    398:   unlink(zFilename);
                    399: #endif
                    400:   return SQLITE_OK;
                    401: }
                    402: 
                    403: /*
                    404: ** Return TRUE if the named file exists.
                    405: */
                    406: int sqliteOsFileExists(const char *zFilename){
                    407: #if OS_UNIX
                    408:   return access(zFilename, 0)==0;
                    409: #endif
                    410: #if OS_WIN
                    411:   return GetFileAttributes(zFilename) != 0xffffffff;
                    412: #endif
                    413: #if OS_MAC
                    414:   return access(zFilename, 0)==0;
                    415: #endif
                    416: }
                    417: 
                    418: 
                    419: #if 0 /* NOT USED */
                    420: /*
                    421: ** Change the name of an existing file.
                    422: */
                    423: int sqliteOsFileRename(const char *zOldName, const char *zNewName){
                    424: #if OS_UNIX
                    425:   if( link(zOldName, zNewName) ){
                    426:     return SQLITE_ERROR;
                    427:   }
                    428:   unlink(zOldName);
                    429:   return SQLITE_OK;
                    430: #endif
                    431: #if OS_WIN
                    432:   if( !MoveFile(zOldName, zNewName) ){
                    433:     return SQLITE_ERROR;
                    434:   }
                    435:   return SQLITE_OK;
                    436: #endif
                    437: #if OS_MAC
                    438:   /**** FIX ME ***/
                    439:   return SQLITE_ERROR;
                    440: #endif
                    441: }
                    442: #endif /* NOT USED */
                    443: 
                    444: /*
                    445: ** Attempt to open a file for both reading and writing.  If that
                    446: ** fails, try opening it read-only.  If the file does not exist,
                    447: ** try to create it.
                    448: **
                    449: ** On success, a handle for the open file is written to *id
                    450: ** and *pReadonly is set to 0 if the file was opened for reading and
                    451: ** writing or 1 if the file was opened read-only.  The function returns
                    452: ** SQLITE_OK.
                    453: **
                    454: ** On failure, the function returns SQLITE_CANTOPEN and leaves
                    455: ** *id and *pReadonly unchanged.
                    456: */
                    457: int sqliteOsOpenReadWrite(
                    458:   const char *zFilename,
                    459:   OsFile *id,
                    460:   int *pReadonly
                    461: ){
                    462: #if OS_UNIX
                    463:   int rc;
                    464:   id->dirfd = -1;
                    465:   id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
                    466:   if( id->fd<0 ){
                    467: #ifdef EISDIR
                    468:     if( errno==EISDIR ){
                    469:       return SQLITE_CANTOPEN;
                    470:     }
                    471: #endif
                    472:     id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
                    473:     if( id->fd<0 ){
                    474:       return SQLITE_CANTOPEN; 
                    475:     }
                    476:     *pReadonly = 1;
                    477:   }else{
                    478:     *pReadonly = 0;
                    479:   }
                    480:   sqliteOsEnterMutex();
                    481:   rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
                    482:   sqliteOsLeaveMutex();
                    483:   if( rc ){
                    484:     close(id->fd);
                    485:     return SQLITE_NOMEM;
                    486:   }
                    487:   id->locked = 0;
                    488:   TRACE3("OPEN    %-3d %s\n", id->fd, zFilename);
                    489:   OpenCounter(+1);
                    490:   return SQLITE_OK;
                    491: #endif
                    492: #if OS_WIN
                    493:   HANDLE h = CreateFile(zFilename,
                    494:      GENERIC_READ | GENERIC_WRITE,
                    495:      FILE_SHARE_READ | FILE_SHARE_WRITE,
                    496:      NULL,
                    497:      OPEN_ALWAYS,
                    498:      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
                    499:      NULL
                    500:   );
                    501:   if( h==INVALID_HANDLE_VALUE ){
                    502:     h = CreateFile(zFilename,
                    503:        GENERIC_READ,
                    504:        FILE_SHARE_READ,
                    505:        NULL,
                    506:        OPEN_ALWAYS,
                    507:        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
                    508:        NULL
                    509:     );
                    510:     if( h==INVALID_HANDLE_VALUE ){
                    511:       return SQLITE_CANTOPEN;
                    512:     }
                    513:     *pReadonly = 1;
                    514:   }else{
                    515:     *pReadonly = 0;
                    516:   }
                    517:   id->h = h;
                    518:   id->locked = 0;
                    519:   OpenCounter(+1);
                    520:   return SQLITE_OK;
                    521: #endif
                    522: #if OS_MAC
                    523:   FSSpec fsSpec;
                    524: # ifdef _LARGE_FILE
                    525:   HFSUniStr255 dfName;
                    526:   FSRef fsRef;
                    527:   if( __path2fss(zFilename, &fsSpec) != noErr ){
                    528:     if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
                    529:       return SQLITE_CANTOPEN;
                    530:   }
                    531:   if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
                    532:     return SQLITE_CANTOPEN;
                    533:   FSGetDataForkName(&dfName);
                    534:   if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
                    535:                  fsRdWrShPerm, &(id->refNum)) != noErr ){
                    536:     if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
                    537:                    fsRdWrPerm, &(id->refNum)) != noErr ){
                    538:       if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
                    539:                    fsRdPerm, &(id->refNum)) != noErr )
                    540:         return SQLITE_CANTOPEN;
                    541:       else
                    542:         *pReadonly = 1;
                    543:     } else
                    544:       *pReadonly = 0;
                    545:   } else
                    546:     *pReadonly = 0;
                    547: # else
                    548:   __path2fss(zFilename, &fsSpec);
                    549:   if( !sqliteOsFileExists(zFilename) ){
                    550:     if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
                    551:       return SQLITE_CANTOPEN;
                    552:   }
                    553:   if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
                    554:     if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
                    555:       if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
                    556:         return SQLITE_CANTOPEN;
                    557:       else
                    558:         *pReadonly = 1;
                    559:     } else
                    560:       *pReadonly = 0;
                    561:   } else
                    562:     *pReadonly = 0;
                    563: # endif
                    564:   if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
                    565:     id->refNumRF = -1;
                    566:   }
                    567:   id->locked = 0;
                    568:   id->delOnClose = 0;
                    569:   OpenCounter(+1);
                    570:   return SQLITE_OK;
                    571: #endif
                    572: }
                    573: 
                    574: 
                    575: /*
                    576: ** Attempt to open a new file for exclusive access by this process.
                    577: ** The file will be opened for both reading and writing.  To avoid
                    578: ** a potential security problem, we do not allow the file to have
                    579: ** previously existed.  Nor do we allow the file to be a symbolic
                    580: ** link.
                    581: **
                    582: ** If delFlag is true, then make arrangements to automatically delete
                    583: ** the file when it is closed.
                    584: **
                    585: ** On success, write the file handle into *id and return SQLITE_OK.
                    586: **
                    587: ** On failure, return SQLITE_CANTOPEN.
                    588: */
                    589: int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
                    590: #if OS_UNIX
                    591:   int rc;
                    592:   if( access(zFilename, 0)==0 ){
                    593:     return SQLITE_CANTOPEN;
                    594:   }
                    595:   id->dirfd = -1;
                    596:   id->fd = open(zFilename,
                    597:                 O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
                    598:   if( id->fd<0 ){
                    599:     return SQLITE_CANTOPEN;
                    600:   }
                    601:   sqliteOsEnterMutex();
                    602:   rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
                    603:   sqliteOsLeaveMutex();
                    604:   if( rc ){
                    605:     close(id->fd);
                    606:     unlink(zFilename);
                    607:     return SQLITE_NOMEM;
                    608:   }
                    609:   id->locked = 0;
                    610:   if( delFlag ){
                    611:     unlink(zFilename);
                    612:   }
                    613:   TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
                    614:   OpenCounter(+1);
                    615:   return SQLITE_OK;
                    616: #endif
                    617: #if OS_WIN
                    618:   HANDLE h;
                    619:   int fileflags;
                    620:   if( delFlag ){
                    621:     fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
                    622:                      | FILE_FLAG_DELETE_ON_CLOSE;
                    623:   }else{
                    624:     fileflags = FILE_FLAG_RANDOM_ACCESS;
                    625:   }
                    626:   h = CreateFile(zFilename,
                    627:      GENERIC_READ | GENERIC_WRITE,
                    628:      0,
                    629:      NULL,
                    630:      CREATE_ALWAYS,
                    631:      fileflags,
                    632:      NULL
                    633:   );
                    634:   if( h==INVALID_HANDLE_VALUE ){
                    635:     return SQLITE_CANTOPEN;
                    636:   }
                    637:   id->h = h;
                    638:   id->locked = 0;
                    639:   OpenCounter(+1);
                    640:   return SQLITE_OK;
                    641: #endif
                    642: #if OS_MAC
                    643:   FSSpec fsSpec;
                    644: # ifdef _LARGE_FILE
                    645:   HFSUniStr255 dfName;
                    646:   FSRef fsRef;
                    647:   __path2fss(zFilename, &fsSpec);
                    648:   if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
                    649:     return SQLITE_CANTOPEN;
                    650:   if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
                    651:     return SQLITE_CANTOPEN;
                    652:   FSGetDataForkName(&dfName);
                    653:   if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
                    654:                  fsRdWrPerm, &(id->refNum)) != noErr )
                    655:     return SQLITE_CANTOPEN;
                    656: # else
                    657:   __path2fss(zFilename, &fsSpec);
                    658:   if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
                    659:     return SQLITE_CANTOPEN;
                    660:   if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
                    661:     return SQLITE_CANTOPEN;
                    662: # endif
                    663:   id->refNumRF = -1;
                    664:   id->locked = 0;
                    665:   id->delOnClose = delFlag;
                    666:   if (delFlag)
                    667:     id->pathToDel = sqliteOsFullPathname(zFilename);
                    668:   OpenCounter(+1);
                    669:   return SQLITE_OK;
                    670: #endif
                    671: }
                    672: 
                    673: /*
                    674: ** Attempt to open a new file for read-only access.
                    675: **
                    676: ** On success, write the file handle into *id and return SQLITE_OK.
                    677: **
                    678: ** On failure, return SQLITE_CANTOPEN.
                    679: */
                    680: int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
                    681: #if OS_UNIX
                    682:   int rc;
                    683:   id->dirfd = -1;
                    684:   id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
                    685:   if( id->fd<0 ){
                    686:     return SQLITE_CANTOPEN;
                    687:   }
                    688:   sqliteOsEnterMutex();
                    689:   rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
                    690:   sqliteOsLeaveMutex();
                    691:   if( rc ){
                    692:     close(id->fd);
                    693:     return SQLITE_NOMEM;
                    694:   }
                    695:   id->locked = 0;
                    696:   TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
                    697:   OpenCounter(+1);
                    698:   return SQLITE_OK;
                    699: #endif
                    700: #if OS_WIN
                    701:   HANDLE h = CreateFile(zFilename,
                    702:      GENERIC_READ,
                    703:      0,
                    704:      NULL,
                    705:      OPEN_EXISTING,
                    706:      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
                    707:      NULL
                    708:   );
                    709:   if( h==INVALID_HANDLE_VALUE ){
                    710:     return SQLITE_CANTOPEN;
                    711:   }
                    712:   id->h = h;
                    713:   id->locked = 0;
                    714:   OpenCounter(+1);
                    715:   return SQLITE_OK;
                    716: #endif
                    717: #if OS_MAC
                    718:   FSSpec fsSpec;
                    719: # ifdef _LARGE_FILE
                    720:   HFSUniStr255 dfName;
                    721:   FSRef fsRef;
                    722:   if( __path2fss(zFilename, &fsSpec) != noErr )
                    723:     return SQLITE_CANTOPEN;
                    724:   if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
                    725:     return SQLITE_CANTOPEN;
                    726:   FSGetDataForkName(&dfName);
                    727:   if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
                    728:                  fsRdPerm, &(id->refNum)) != noErr )
                    729:     return SQLITE_CANTOPEN;
                    730: # else
                    731:   __path2fss(zFilename, &fsSpec);
                    732:   if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
                    733:     return SQLITE_CANTOPEN;
                    734: # endif
                    735:   if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
                    736:     id->refNumRF = -1;
                    737:   }
                    738:   id->locked = 0;
                    739:   id->delOnClose = 0;
                    740:   OpenCounter(+1);
                    741:   return SQLITE_OK;
                    742: #endif
                    743: }
                    744: 
                    745: /*
                    746: ** Attempt to open a file descriptor for the directory that contains a
                    747: ** file.  This file descriptor can be used to fsync() the directory
                    748: ** in order to make sure the creation of a new file is actually written
                    749: ** to disk.
                    750: **
                    751: ** This routine is only meaningful for Unix.  It is a no-op under
                    752: ** windows since windows does not support hard links.
                    753: **
                    754: ** On success, a handle for a previously open file is at *id is
                    755: ** updated with the new directory file descriptor and SQLITE_OK is
                    756: ** returned.
                    757: **
                    758: ** On failure, the function returns SQLITE_CANTOPEN and leaves
                    759: ** *id unchanged.
                    760: */
                    761: int sqliteOsOpenDirectory(
                    762:   const char *zDirname,
                    763:   OsFile *id
                    764: ){
                    765: #if OS_UNIX
                    766:   if( id->fd<0 ){
                    767:     /* Do not open the directory if the corresponding file is not already
                    768:     ** open. */
                    769:     return SQLITE_CANTOPEN;
                    770:   }
                    771:   assert( id->dirfd<0 );
                    772:   id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
                    773:   if( id->dirfd<0 ){
                    774:     return SQLITE_CANTOPEN; 
                    775:   }
                    776:   TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
                    777: #endif
                    778:   return SQLITE_OK;
                    779: }
                    780: 
                    781: /*
                    782: ** If the following global variable points to a string which is the
                    783: ** name of a directory, then that directory will be used to store
                    784: ** temporary files.
                    785: */
                    786: const char *sqlite_temp_directory = 0;
                    787: 
                    788: /*
                    789: ** Create a temporary file name in zBuf.  zBuf must be big enough to
                    790: ** hold at least SQLITE_TEMPNAME_SIZE characters.
                    791: */
                    792: int sqliteOsTempFileName(char *zBuf){
                    793: #if OS_UNIX
                    794:   static const char *azDirs[] = {
                    795:      0,
                    796:      "/var/tmp",
                    797:      "/usr/tmp",
                    798:      "/tmp",
                    799:      ".",
                    800:   };
                    801:   static unsigned char zChars[] =
                    802:     "abcdefghijklmnopqrstuvwxyz"
                    803:     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    804:     "0123456789";
                    805:   int i, j;
                    806:   struct stat buf;
                    807:   const char *zDir = ".";
                    808:   azDirs[0] = sqlite_temp_directory;
                    809:   for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
                    810:     if( azDirs[i]==0 ) continue;
                    811:     if( stat(azDirs[i], &buf) ) continue;
                    812:     if( !S_ISDIR(buf.st_mode) ) continue;
                    813:     if( access(azDirs[i], 07) ) continue;
                    814:     zDir = azDirs[i];
                    815:     break;
                    816:   }
                    817:   do{
                    818:     sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
                    819:     j = strlen(zBuf);
                    820:     sqliteRandomness(15, &zBuf[j]);
                    821:     for(i=0; i<15; i++, j++){
                    822:       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
                    823:     }
                    824:     zBuf[j] = 0;
                    825:   }while( access(zBuf,0)==0 );
                    826: #endif
                    827: #if OS_WIN
                    828:   static char zChars[] =
                    829:     "abcdefghijklmnopqrstuvwxyz"
                    830:     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    831:     "0123456789";
                    832:   int i, j;
                    833:   const char *zDir;
                    834:   char zTempPath[SQLITE_TEMPNAME_SIZE];
                    835:   if( sqlite_temp_directory==0 ){
                    836:     GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
                    837:     for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
                    838:     zTempPath[i] = 0;
                    839:     zDir = zTempPath;
                    840:   }else{
                    841:     zDir = sqlite_temp_directory;
                    842:   }
                    843:   for(;;){
                    844:     sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zDir);
                    845:     j = strlen(zBuf);
                    846:     sqliteRandomness(15, &zBuf[j]);
                    847:     for(i=0; i<15; i++, j++){
                    848:       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
                    849:     }
                    850:     zBuf[j] = 0;
                    851:     if( !sqliteOsFileExists(zBuf) ) break;
                    852:   }
                    853: #endif
                    854: #if OS_MAC
                    855:   static char zChars[] =
                    856:     "abcdefghijklmnopqrstuvwxyz"
                    857:     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    858:     "0123456789";
                    859:   int i, j;
                    860:   char *zDir;
                    861:   char zTempPath[SQLITE_TEMPNAME_SIZE];
                    862:   char zdirName[32];
                    863:   CInfoPBRec infoRec;
                    864:   Str31 dirName;
                    865:   memset(&infoRec, 0, sizeof(infoRec));
                    866:   memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
                    867:   if( sqlite_temp_directory!=0 ){
                    868:     zDir = sqlite_temp_directory;
                    869:   }else if( FindFolder(kOnSystemDisk, kTemporaryFolderType,  kCreateFolder,
                    870:        &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
                    871:     infoRec.dirInfo.ioNamePtr = dirName;
                    872:     do{
                    873:       infoRec.dirInfo.ioFDirIndex = -1;
                    874:       infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
                    875:       if( PBGetCatInfoSync(&infoRec) == noErr ){
                    876:         CopyPascalStringToC(dirName, zdirName);
                    877:         i = strlen(zdirName);
                    878:         memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
                    879:         strcpy(zTempPath, zdirName);
                    880:         zTempPath[i] = ':';
                    881:       }else{
                    882:         *zTempPath = 0;
                    883:         break;
                    884:       }
                    885:     } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
                    886:     zDir = zTempPath;
                    887:   }
                    888:   if( zDir[0]==0 ){
                    889:     getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
                    890:     zDir = zTempPath;
                    891:   }
                    892:   for(;;){
                    893:     sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zDir);
                    894:     j = strlen(zBuf);
                    895:     sqliteRandomness(15, &zBuf[j]);
                    896:     for(i=0; i<15; i++, j++){
                    897:       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
                    898:     }
                    899:     zBuf[j] = 0;
                    900:     if( !sqliteOsFileExists(zBuf) ) break;
                    901:   }
                    902: #endif
                    903:   return SQLITE_OK; 
                    904: }
                    905: 
                    906: /*
                    907: ** Close a file.
                    908: */
                    909: int sqliteOsClose(OsFile *id){
                    910: #if OS_UNIX
                    911:   sqliteOsUnlock(id);
                    912:   if( id->dirfd>=0 ) close(id->dirfd);
                    913:   id->dirfd = -1;
                    914:   sqliteOsEnterMutex();
                    915:   if( id->pOpen->nLock ){
                    916:     /* If there are outstanding locks, do not actually close the file just
                    917:     ** yet because that would clear those locks.  Instead, add the file
                    918:     ** descriptor to pOpen->aPending.  It will be automatically closed when
                    919:     ** the last lock is cleared.
                    920:     */
                    921:     int *aNew;
                    922:     struct openCnt *pOpen = id->pOpen;
                    923:     pOpen->nPending++;
                    924:     aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
                    925:     if( aNew==0 ){
                    926:       /* If a malloc fails, just leak the file descriptor */
                    927:     }else{
                    928:       pOpen->aPending = aNew;
                    929:       pOpen->aPending[pOpen->nPending-1] = id->fd;
                    930:     }
                    931:   }else{
                    932:     /* There are no outstanding locks so we can close the file immediately */
                    933:     close(id->fd);
                    934:   }
                    935:   releaseLockInfo(id->pLock);
                    936:   releaseOpenCnt(id->pOpen);
                    937:   sqliteOsLeaveMutex();
                    938:   TRACE2("CLOSE   %-3d\n", id->fd);
                    939:   OpenCounter(-1);
                    940:   return SQLITE_OK;
                    941: #endif
                    942: #if OS_WIN
                    943:   CloseHandle(id->h);
                    944:   OpenCounter(-1);
                    945:   return SQLITE_OK;
                    946: #endif
                    947: #if OS_MAC
                    948:   if( id->refNumRF!=-1 )
                    949:     FSClose(id->refNumRF);
                    950: # ifdef _LARGE_FILE
                    951:   FSCloseFork(id->refNum);
                    952: # else
                    953:   FSClose(id->refNum);
                    954: # endif
                    955:   if( id->delOnClose ){
                    956:     unlink(id->pathToDel);
                    957:     sqliteFree(id->pathToDel);
                    958:   }
                    959:   OpenCounter(-1);
                    960:   return SQLITE_OK;
                    961: #endif
                    962: }
                    963: 
                    964: /*
                    965: ** Read data from a file into a buffer.  Return SQLITE_OK if all
                    966: ** bytes were read successfully and SQLITE_IOERR if anything goes
                    967: ** wrong.
                    968: */
                    969: int sqliteOsRead(OsFile *id, void *pBuf, int amt){
                    970: #if OS_UNIX
                    971:   int got;
                    972:   SimulateIOError(SQLITE_IOERR);
                    973:   TIMER_START;
                    974:   got = read(id->fd, pBuf, amt);
                    975:   TIMER_END;
                    976:   TRACE4("READ    %-3d %7d %d\n", id->fd, last_page, elapse);
                    977:   SEEK(0);
                    978:   /* if( got<0 ) got = 0; */
                    979:   if( got==amt ){
                    980:     return SQLITE_OK;
                    981:   }else{
                    982:     return SQLITE_IOERR;
                    983:   }
                    984: #endif
                    985: #if OS_WIN
                    986:   DWORD got;
                    987:   SimulateIOError(SQLITE_IOERR);
                    988:   TRACE2("READ %d\n", last_page);
                    989:   if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
                    990:     got = 0;
                    991:   }
                    992:   if( got==(DWORD)amt ){
                    993:     return SQLITE_OK;
                    994:   }else{
                    995:     return SQLITE_IOERR;
                    996:   }
                    997: #endif
                    998: #if OS_MAC
                    999:   int got;
                   1000:   SimulateIOError(SQLITE_IOERR);
                   1001:   TRACE2("READ %d\n", last_page);
                   1002: # ifdef _LARGE_FILE
                   1003:   FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
                   1004: # else
                   1005:   got = amt;
                   1006:   FSRead(id->refNum, &got, pBuf);
                   1007: # endif
                   1008:   if( got==amt ){
                   1009:     return SQLITE_OK;
                   1010:   }else{
                   1011:     return SQLITE_IOERR;
                   1012:   }
                   1013: #endif
                   1014: }
                   1015: 
                   1016: /*
                   1017: ** Write data from a buffer into a file.  Return SQLITE_OK on success
                   1018: ** or some other error code on failure.
                   1019: */
                   1020: int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
                   1021: #if OS_UNIX
                   1022:   int wrote = 0;
                   1023:   SimulateIOError(SQLITE_IOERR);
                   1024:   TIMER_START;
                   1025:   while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
                   1026:     amt -= wrote;
                   1027:     pBuf = &((char*)pBuf)[wrote];
                   1028:   }
                   1029:   TIMER_END;
                   1030:   TRACE4("WRITE   %-3d %7d %d\n", id->fd, last_page, elapse);
                   1031:   SEEK(0);
                   1032:   if( amt>0 ){
                   1033:     return SQLITE_FULL;
                   1034:   }
                   1035:   return SQLITE_OK;
                   1036: #endif
                   1037: #if OS_WIN
                   1038:   int rc;
                   1039:   DWORD wrote;
                   1040:   SimulateIOError(SQLITE_IOERR);
                   1041:   TRACE2("WRITE %d\n", last_page);
                   1042:   while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
                   1043:     amt -= wrote;
                   1044:     pBuf = &((char*)pBuf)[wrote];
                   1045:   }
                   1046:   if( !rc || amt>(int)wrote ){
                   1047:     return SQLITE_FULL;
                   1048:   }
                   1049:   return SQLITE_OK;
                   1050: #endif
                   1051: #if OS_MAC
                   1052:   OSErr oserr;
                   1053:   int wrote = 0;
                   1054:   SimulateIOError(SQLITE_IOERR);
                   1055:   TRACE2("WRITE %d\n", last_page);
                   1056:   while( amt>0 ){
                   1057: # ifdef _LARGE_FILE
                   1058:     oserr = FSWriteFork(id->refNum, fsAtMark, 0,
                   1059:                         (ByteCount)amt, pBuf, (ByteCount*)&wrote);
                   1060: # else
                   1061:     wrote = amt;
                   1062:     oserr = FSWrite(id->refNum, &wrote, pBuf);
                   1063: # endif
                   1064:     if( wrote == 0 || oserr != noErr)
                   1065:       break;
                   1066:     amt -= wrote;
                   1067:     pBuf = &((char*)pBuf)[wrote];
                   1068:   }
                   1069:   if( oserr != noErr || amt>wrote ){
                   1070:     return SQLITE_FULL;
                   1071:   }
                   1072:   return SQLITE_OK;
                   1073: #endif
                   1074: }
                   1075: 
                   1076: /*
                   1077: ** Move the read/write pointer in a file.
                   1078: */
                   1079: int sqliteOsSeek(OsFile *id, off_t offset){
                   1080:   SEEK(offset/1024 + 1);
                   1081: #if OS_UNIX
                   1082:   lseek(id->fd, offset, SEEK_SET);
                   1083:   return SQLITE_OK;
                   1084: #endif
                   1085: #if OS_WIN
                   1086:   {
                   1087:     LONG upperBits = offset>>32;
                   1088:     LONG lowerBits = offset & 0xffffffff;
                   1089:     DWORD rc;
                   1090:     rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
                   1091:     /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
                   1092:   }
                   1093:   return SQLITE_OK;
                   1094: #endif
                   1095: #if OS_MAC
                   1096:   {
                   1097:     off_t curSize;
                   1098:     if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){
                   1099:       return SQLITE_IOERR;
                   1100:     }
                   1101:     if( offset >= curSize ){
                   1102:       if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){
                   1103:         return SQLITE_IOERR;
                   1104:       }
                   1105:     }
                   1106: # ifdef _LARGE_FILE
                   1107:     if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
                   1108: # else
                   1109:     if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
                   1110: # endif
                   1111:       return SQLITE_IOERR;
                   1112:     }else{
                   1113:       return SQLITE_OK;
                   1114:     }
                   1115:   }
                   1116: #endif
                   1117: }
                   1118: 
                   1119: #ifdef SQLITE_NOSYNC
                   1120: # define fsync(X) 0
                   1121: #endif
                   1122: 
                   1123: /*
                   1124: ** Make sure all writes to a particular file are committed to disk.
                   1125: **
                   1126: ** Under Unix, also make sure that the directory entry for the file
                   1127: ** has been created by fsync-ing the directory that contains the file.
                   1128: ** If we do not do this and we encounter a power failure, the directory
                   1129: ** entry for the journal might not exist after we reboot.  The next
                   1130: ** SQLite to access the file will not know that the journal exists (because
                   1131: ** the directory entry for the journal was never created) and the transaction
                   1132: ** will not roll back - possibly leading to database corruption.
                   1133: */
                   1134: int sqliteOsSync(OsFile *id){
                   1135: #if OS_UNIX
                   1136:   SimulateIOError(SQLITE_IOERR);
                   1137:   TRACE2("SYNC    %-3d\n", id->fd);
                   1138:   if( fsync(id->fd) ){
                   1139:     return SQLITE_IOERR;
                   1140:   }else{
                   1141:     if( id->dirfd>=0 ){
                   1142:       TRACE2("DIRSYNC %-3d\n", id->dirfd);
                   1143:       fsync(id->dirfd);
                   1144:       close(id->dirfd);  /* Only need to sync once, so close the directory */
                   1145:       id->dirfd = -1;    /* when we are done. */
                   1146:     }
                   1147:     return SQLITE_OK;
                   1148:   }
                   1149: #endif
                   1150: #if OS_WIN
                   1151:   if( FlushFileBuffers(id->h) ){
                   1152:     return SQLITE_OK;
                   1153:   }else{
                   1154:     return SQLITE_IOERR;
                   1155:   }
                   1156: #endif
                   1157: #if OS_MAC
                   1158: # ifdef _LARGE_FILE
                   1159:   if( FSFlushFork(id->refNum) != noErr ){
                   1160: # else
                   1161:   ParamBlockRec params;
                   1162:   memset(&params, 0, sizeof(ParamBlockRec));
                   1163:   params.ioParam.ioRefNum = id->refNum;
                   1164:   if( PBFlushFileSync(&params) != noErr ){
                   1165: # endif
                   1166:     return SQLITE_IOERR;
                   1167:   }else{
                   1168:     return SQLITE_OK;
                   1169:   }
                   1170: #endif
                   1171: }
                   1172: 
                   1173: /*
                   1174: ** Truncate an open file to a specified size
                   1175: */
                   1176: int sqliteOsTruncate(OsFile *id, off_t nByte){
                   1177:   SimulateIOError(SQLITE_IOERR);
                   1178: #if OS_UNIX
                   1179:   return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
                   1180: #endif
                   1181: #if OS_WIN
                   1182:   {
                   1183:     LONG upperBits = nByte>>32;
                   1184:     SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
                   1185:     SetEndOfFile(id->h);
                   1186:   }
                   1187:   return SQLITE_OK;
                   1188: #endif
                   1189: #if OS_MAC
                   1190: # ifdef _LARGE_FILE
                   1191:   if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
                   1192: # else
                   1193:   if( SetEOF(id->refNum, nByte) != noErr ){
                   1194: # endif
                   1195:     return SQLITE_IOERR;
                   1196:   }else{
                   1197:     return SQLITE_OK;
                   1198:   }
                   1199: #endif
                   1200: }
                   1201: 
                   1202: /*
                   1203: ** Determine the current size of a file in bytes
                   1204: */
                   1205: int sqliteOsFileSize(OsFile *id, off_t *pSize){
                   1206: #if OS_UNIX
                   1207:   struct stat buf;
                   1208:   SimulateIOError(SQLITE_IOERR);
                   1209:   if( fstat(id->fd, &buf)!=0 ){
                   1210:     return SQLITE_IOERR;
                   1211:   }
                   1212:   *pSize = buf.st_size;
                   1213:   return SQLITE_OK;
                   1214: #endif
                   1215: #if OS_WIN
                   1216:   DWORD upperBits, lowerBits;
                   1217:   SimulateIOError(SQLITE_IOERR);
                   1218:   lowerBits = GetFileSize(id->h, &upperBits);
                   1219:   *pSize = (((off_t)upperBits)<<32) + lowerBits;
                   1220:   return SQLITE_OK;
                   1221: #endif
                   1222: #if OS_MAC
                   1223: # ifdef _LARGE_FILE
                   1224:   if( FSGetForkSize(id->refNum, pSize) != noErr){
                   1225: # else
                   1226:   if( GetEOF(id->refNum, pSize) != noErr ){
                   1227: # endif
                   1228:     return SQLITE_IOERR;
                   1229:   }else{
                   1230:     return SQLITE_OK;
                   1231:   }
                   1232: #endif
                   1233: }
                   1234: 
                   1235: #if OS_WIN
                   1236: /*
                   1237: ** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
                   1238: ** Return false (zero) for Win95, Win98, or WinME.
                   1239: **
                   1240: ** Here is an interesting observation:  Win95, Win98, and WinME lack
                   1241: ** the LockFileEx() API.  But we can still statically link against that
                   1242: ** API as long as we don't call it win running Win95/98/ME.  A call to
                   1243: ** this routine is used to determine if the host is Win95/98/ME or
                   1244: ** WinNT/2K/XP so that we will know whether or not we can safely call
                   1245: ** the LockFileEx() API.
                   1246: */
                   1247: int isNT(void){
                   1248:   static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
                   1249:   if( osType==0 ){
                   1250:     OSVERSIONINFO sInfo;
                   1251:     sInfo.dwOSVersionInfoSize = sizeof(sInfo);
                   1252:     GetVersionEx(&sInfo);
                   1253:     osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
                   1254:   }
                   1255:   return osType==2;
                   1256: }
                   1257: #endif
                   1258: 
                   1259: /*
                   1260: ** Windows file locking notes:  [similar issues apply to MacOS]
                   1261: **
                   1262: ** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
                   1263: ** those functions are not available.  So we use only LockFile() and
                   1264: ** UnlockFile().
                   1265: **
                   1266: ** LockFile() prevents not just writing but also reading by other processes.
                   1267: ** (This is a design error on the part of Windows, but there is nothing
                   1268: ** we can do about that.)  So the region used for locking is at the
                   1269: ** end of the file where it is unlikely to ever interfere with an
                   1270: ** actual read attempt.
                   1271: **
                   1272: ** A database read lock is obtained by locking a single randomly-chosen 
                   1273: ** byte out of a specific range of bytes. The lock byte is obtained at 
                   1274: ** random so two separate readers can probably access the file at the 
                   1275: ** same time, unless they are unlucky and choose the same lock byte.
                   1276: ** A database write lock is obtained by locking all bytes in the range.
                   1277: ** There can only be one writer.
                   1278: **
                   1279: ** A lock is obtained on the first byte of the lock range before acquiring
                   1280: ** either a read lock or a write lock.  This prevents two processes from
                   1281: ** attempting to get a lock at a same time.  The semantics of 
                   1282: ** sqliteOsReadLock() require that if there is already a write lock, that
                   1283: ** lock is converted into a read lock atomically.  The lock on the first
                   1284: ** byte allows us to drop the old write lock and get the read lock without
                   1285: ** another process jumping into the middle and messing us up.  The same
                   1286: ** argument applies to sqliteOsWriteLock().
                   1287: **
                   1288: ** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
                   1289: ** which means we can use reader/writer locks.  When reader writer locks
                   1290: ** are used, the lock is placed on the same range of bytes that is used
                   1291: ** for probabilistic locking in Win95/98/ME.  Hence, the locking scheme
                   1292: ** will support two or more Win95 readers or two or more WinNT readers.
                   1293: ** But a single Win95 reader will lock out all WinNT readers and a single
                   1294: ** WinNT reader will lock out all other Win95 readers.
                   1295: **
                   1296: ** Note: On MacOS we use the resource fork for locking.
                   1297: **
                   1298: ** The following #defines specify the range of bytes used for locking.
                   1299: ** N_LOCKBYTE is the number of bytes available for doing the locking.
                   1300: ** The first byte used to hold the lock while the lock is changing does
                   1301: ** not count toward this number.  FIRST_LOCKBYTE is the address of
                   1302: ** the first byte in the range of bytes used for locking.
                   1303: */
                   1304: #define N_LOCKBYTE       10239
                   1305: #if OS_MAC
                   1306: # define FIRST_LOCKBYTE   (0x000fffff - N_LOCKBYTE)
                   1307: #else
                   1308: # define FIRST_LOCKBYTE   (0xffffffff - N_LOCKBYTE)
                   1309: #endif
                   1310: 
                   1311: /*
                   1312: ** Change the status of the lock on the file "id" to be a readlock.
                   1313: ** If the file was write locked, then this reduces the lock to a read.
                   1314: ** If the file was read locked, then this acquires a new read lock.
                   1315: **
                   1316: ** Return SQLITE_OK on success and SQLITE_BUSY on failure.  If this
                   1317: ** library was compiled with large file support (LFS) but LFS is not
                   1318: ** available on the host, then an SQLITE_NOLFS is returned.
                   1319: */
                   1320: int sqliteOsReadLock(OsFile *id){
                   1321: #if OS_UNIX
                   1322:   int rc;
                   1323:   sqliteOsEnterMutex();
                   1324:   if( id->pLock->cnt>0 ){
                   1325:     if( !id->locked ){
                   1326:       id->pLock->cnt++;
                   1327:       id->locked = 1;
                   1328:       id->pOpen->nLock++;
                   1329:     }
                   1330:     rc = SQLITE_OK;
                   1331:   }else if( id->locked || id->pLock->cnt==0 ){
                   1332:     struct flock lock;
                   1333:     int s;
                   1334:     lock.l_type = F_RDLCK;
                   1335:     lock.l_whence = SEEK_SET;
                   1336:     lock.l_start = lock.l_len = 0L;
                   1337:     s = fcntl(id->fd, F_SETLK, &lock);
                   1338:     if( s!=0 ){
                   1339:       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
                   1340:     }else{
                   1341:       rc = SQLITE_OK;
                   1342:       if( !id->locked ){
                   1343:         id->pOpen->nLock++;
                   1344:         id->locked = 1;
                   1345:       }
                   1346:       id->pLock->cnt = 1;
                   1347:     }
                   1348:   }else{
                   1349:     rc = SQLITE_BUSY;
                   1350:   }
                   1351:   sqliteOsLeaveMutex();
                   1352:   return rc;
                   1353: #endif
                   1354: #if OS_WIN
                   1355:   int rc;
                   1356:   if( id->locked>0 ){
                   1357:     rc = SQLITE_OK;
                   1358:   }else{
                   1359:     int lk;
                   1360:     int res;
                   1361:     int cnt = 100;
                   1362:     sqliteRandomness(sizeof(lk), &lk);
                   1363:     lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
                   1364:     while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
                   1365:       Sleep(1);
                   1366:     }
                   1367:     if( res ){
                   1368:       UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
                   1369:       if( isNT() ){
                   1370:         OVERLAPPED ovlp;
                   1371:         ovlp.Offset = FIRST_LOCKBYTE+1;
                   1372:         ovlp.OffsetHigh = 0;
                   1373:         ovlp.hEvent = 0;
                   1374:         res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 
                   1375:                           0, N_LOCKBYTE, 0, &ovlp);
                   1376:       }else{
                   1377:         res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
                   1378:       }
                   1379:       UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
                   1380:     }
                   1381:     if( res ){
                   1382:       id->locked = lk;
                   1383:       rc = SQLITE_OK;
                   1384:     }else{
                   1385:       rc = SQLITE_BUSY;
                   1386:     }
                   1387:   }
                   1388:   return rc;
                   1389: #endif
                   1390: #if OS_MAC
                   1391:   int rc;
                   1392:   if( id->locked>0 || id->refNumRF == -1 ){
                   1393:     rc = SQLITE_OK;
                   1394:   }else{
                   1395:     int lk;
                   1396:     OSErr res;
                   1397:     int cnt = 5;
                   1398:     ParamBlockRec params;
                   1399:     sqliteRandomness(sizeof(lk), &lk);
                   1400:     lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
                   1401:     memset(&params, 0, sizeof(params));
                   1402:     params.ioParam.ioRefNum = id->refNumRF;
                   1403:     params.ioParam.ioPosMode = fsFromStart;
                   1404:     params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
                   1405:     params.ioParam.ioReqCount = 1;
                   1406:     while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
                   1407:       UInt32 finalTicks;
                   1408:       Delay(1, &finalTicks); /* 1/60 sec */
                   1409:     }
                   1410:     if( res == noErr ){
                   1411:       params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
                   1412:       params.ioParam.ioReqCount = N_LOCKBYTE;
                   1413:       PBUnlockRangeSync(&params);
                   1414:       params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
                   1415:       params.ioParam.ioReqCount = 1;
                   1416:       res = PBLockRangeSync(&params);
                   1417:       params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
                   1418:       params.ioParam.ioReqCount = 1;
                   1419:       PBUnlockRangeSync(&params);
                   1420:     }
                   1421:     if( res == noErr ){
                   1422:       id->locked = lk;
                   1423:       rc = SQLITE_OK;
                   1424:     }else{
                   1425:       rc = SQLITE_BUSY;
                   1426:     }
                   1427:   }
                   1428:   return rc;
                   1429: #endif
                   1430: }
                   1431: 
                   1432: /*
                   1433: ** Change the lock status to be an exclusive or write lock.  Return
                   1434: ** SQLITE_OK on success and SQLITE_BUSY on a failure.  If this
                   1435: ** library was compiled with large file support (LFS) but LFS is not
                   1436: ** available on the host, then an SQLITE_NOLFS is returned.
                   1437: */
                   1438: int sqliteOsWriteLock(OsFile *id){
                   1439: #if OS_UNIX
                   1440:   int rc;
                   1441:   sqliteOsEnterMutex();
                   1442:   if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
                   1443:     struct flock lock;
                   1444:     int s;
                   1445:     lock.l_type = F_WRLCK;
                   1446:     lock.l_whence = SEEK_SET;
                   1447:     lock.l_start = lock.l_len = 0L;
                   1448:     s = fcntl(id->fd, F_SETLK, &lock);
                   1449:     if( s!=0 ){
                   1450:       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
                   1451:     }else{
                   1452:       rc = SQLITE_OK;
                   1453:       if( !id->locked ){
                   1454:         id->pOpen->nLock++;
                   1455:         id->locked = 1;
                   1456:       }
                   1457:       id->pLock->cnt = -1;
                   1458:     }
                   1459:   }else{
                   1460:     rc = SQLITE_BUSY;
                   1461:   }
                   1462:   sqliteOsLeaveMutex();
                   1463:   return rc;
                   1464: #endif
                   1465: #if OS_WIN
                   1466:   int rc;
                   1467:   if( id->locked<0 ){
                   1468:     rc = SQLITE_OK;
                   1469:   }else{
                   1470:     int res;
                   1471:     int cnt = 100;
                   1472:     while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
                   1473:       Sleep(1);
                   1474:     }
                   1475:     if( res ){
                   1476:       if( id->locked>0 ){
                   1477:         if( isNT() ){
                   1478:           UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
                   1479:         }else{
                   1480:           res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
                   1481:         }
                   1482:       }
                   1483:       if( res ){
                   1484:         res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
                   1485:       }else{
                   1486:         res = 0;
                   1487:       }
                   1488:       UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
                   1489:     }
                   1490:     if( res ){
                   1491:       id->locked = -1;
                   1492:       rc = SQLITE_OK;
                   1493:     }else{
                   1494:       rc = SQLITE_BUSY;
                   1495:     }
                   1496:   }
                   1497:   return rc;
                   1498: #endif
                   1499: #if OS_MAC
                   1500:   int rc;
                   1501:   if( id->locked<0 || id->refNumRF == -1 ){
                   1502:     rc = SQLITE_OK;
                   1503:   }else{
                   1504:     OSErr res;
                   1505:     int cnt = 5;
                   1506:     ParamBlockRec params;
                   1507:     memset(&params, 0, sizeof(params));
                   1508:     params.ioParam.ioRefNum = id->refNumRF;
                   1509:     params.ioParam.ioPosMode = fsFromStart;
                   1510:     params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
                   1511:     params.ioParam.ioReqCount = 1;
                   1512:     while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
                   1513:       UInt32 finalTicks;
                   1514:       Delay(1, &finalTicks); /* 1/60 sec */
                   1515:     }
                   1516:     if( res == noErr ){
                   1517:       params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
                   1518:       params.ioParam.ioReqCount = 1;
                   1519:       if( id->locked==0 
                   1520:             || PBUnlockRangeSync(&params)==noErr ){
                   1521:         params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
                   1522:         params.ioParam.ioReqCount = N_LOCKBYTE;
                   1523:         res = PBLockRangeSync(&params);
                   1524:       }else{
                   1525:         res = afpRangeNotLocked;
                   1526:       }
                   1527:       params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
                   1528:       params.ioParam.ioReqCount = 1;
                   1529:       PBUnlockRangeSync(&params);
                   1530:     }
                   1531:     if( res == noErr ){
                   1532:       id->locked = -1;
                   1533:       rc = SQLITE_OK;
                   1534:     }else{
                   1535:       rc = SQLITE_BUSY;
                   1536:     }
                   1537:   }
                   1538:   return rc;
                   1539: #endif
                   1540: }
                   1541: 
                   1542: /*
                   1543: ** Unlock the given file descriptor.  If the file descriptor was
                   1544: ** not previously locked, then this routine is a no-op.  If this
                   1545: ** library was compiled with large file support (LFS) but LFS is not
                   1546: ** available on the host, then an SQLITE_NOLFS is returned.
                   1547: */
                   1548: int sqliteOsUnlock(OsFile *id){
                   1549: #if OS_UNIX
                   1550:   int rc;
                   1551:   if( !id->locked ) return SQLITE_OK;
                   1552:   sqliteOsEnterMutex();
                   1553:   assert( id->pLock->cnt!=0 );
                   1554:   if( id->pLock->cnt>1 ){
                   1555:     id->pLock->cnt--;
                   1556:     rc = SQLITE_OK;
                   1557:   }else{
                   1558:     struct flock lock;
                   1559:     int s;
                   1560:     lock.l_type = F_UNLCK;
                   1561:     lock.l_whence = SEEK_SET;
                   1562:     lock.l_start = lock.l_len = 0L;
                   1563:     s = fcntl(id->fd, F_SETLK, &lock);
                   1564:     if( s!=0 ){
                   1565:       rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
                   1566:     }else{
                   1567:       rc = SQLITE_OK;
                   1568:       id->pLock->cnt = 0;
                   1569:     }
                   1570:   }
                   1571:   if( rc==SQLITE_OK ){
                   1572:     /* Decrement the count of locks against this same file.  When the
                   1573:     ** count reaches zero, close any other file descriptors whose close
                   1574:     ** was deferred because of outstanding locks.
                   1575:     */
                   1576:     struct openCnt *pOpen = id->pOpen;
                   1577:     pOpen->nLock--;
                   1578:     assert( pOpen->nLock>=0 );
                   1579:     if( pOpen->nLock==0 && pOpen->nPending>0 ){
                   1580:       int i;
                   1581:       for(i=0; i<pOpen->nPending; i++){
                   1582:         close(pOpen->aPending[i]);
                   1583:       }
                   1584:       sqliteFree(pOpen->aPending);
                   1585:       pOpen->nPending = 0;
                   1586:       pOpen->aPending = 0;
                   1587:     }
                   1588:   }
                   1589:   sqliteOsLeaveMutex();
                   1590:   id->locked = 0;
                   1591:   return rc;
                   1592: #endif
                   1593: #if OS_WIN
                   1594:   int rc;
                   1595:   if( id->locked==0 ){
                   1596:     rc = SQLITE_OK;
                   1597:   }else if( isNT() || id->locked<0 ){
                   1598:     UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
                   1599:     rc = SQLITE_OK;
                   1600:     id->locked = 0;
                   1601:   }else{
                   1602:     UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
                   1603:     rc = SQLITE_OK;
                   1604:     id->locked = 0;
                   1605:   }
                   1606:   return rc;
                   1607: #endif
                   1608: #if OS_MAC
                   1609:   int rc;
                   1610:   ParamBlockRec params;
                   1611:   memset(&params, 0, sizeof(params));
                   1612:   params.ioParam.ioRefNum = id->refNumRF;
                   1613:   params.ioParam.ioPosMode = fsFromStart;
                   1614:   if( id->locked==0 || id->refNumRF == -1 ){
                   1615:     rc = SQLITE_OK;
                   1616:   }else if( id->locked<0 ){
                   1617:     params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
                   1618:     params.ioParam.ioReqCount = N_LOCKBYTE;
                   1619:     PBUnlockRangeSync(&params);
                   1620:     rc = SQLITE_OK;
                   1621:     id->locked = 0;
                   1622:   }else{
                   1623:     params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
                   1624:     params.ioParam.ioReqCount = 1;
                   1625:     PBUnlockRangeSync(&params);
                   1626:     rc = SQLITE_OK;
                   1627:     id->locked = 0;
                   1628:   }
                   1629:   return rc;
                   1630: #endif
                   1631: }
                   1632: 
                   1633: /*
                   1634: ** Get information to seed the random number generator.  The seed
                   1635: ** is written into the buffer zBuf[256].  The calling function must
                   1636: ** supply a sufficiently large buffer.
                   1637: */
                   1638: int sqliteOsRandomSeed(char *zBuf){
                   1639:   /* We have to initialize zBuf to prevent valgrind from reporting
                   1640:   ** errors.  The reports issued by valgrind are incorrect - we would
                   1641:   ** prefer that the randomness be increased by making use of the
                   1642:   ** uninitialized space in zBuf - but valgrind errors tend to worry
                   1643:   ** some users.  Rather than argue, it seems easier just to initialize
                   1644:   ** the whole array and silence valgrind, even if that means less randomness
                   1645:   ** in the random seed.
                   1646:   **
                   1647:   ** When testing, initializing zBuf[] to zero is all we do.  That means
                   1648:   ** that we always use the same random number sequence.* This makes the
                   1649:   ** tests repeatable.
                   1650:   */
                   1651:   memset(zBuf, 0, 256);
                   1652: #if OS_UNIX && !defined(SQLITE_TEST)
                   1653:   {
                   1654:     int pid;
                   1655:     time((time_t*)zBuf);
                   1656:     pid = getpid();
                   1657:     memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
                   1658:   }
                   1659: #endif
                   1660: #if OS_WIN && !defined(SQLITE_TEST)
                   1661:   GetSystemTime((LPSYSTEMTIME)zBuf);
                   1662: #endif
                   1663: #if OS_MAC
                   1664:   {
                   1665:     int pid;
                   1666:     Microseconds((UnsignedWide*)zBuf);
                   1667:     pid = getpid();
                   1668:     memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
                   1669:   }
                   1670: #endif
                   1671:   return SQLITE_OK;
                   1672: }
                   1673: 
                   1674: /*
                   1675: ** Sleep for a little while.  Return the amount of time slept.
                   1676: */
                   1677: int sqliteOsSleep(int ms){
                   1678: #if OS_UNIX
                   1679: #if defined(HAVE_USLEEP) && HAVE_USLEEP
                   1680:   usleep(ms*1000);
                   1681:   return ms;
                   1682: #else
                   1683:   sleep((ms+999)/1000);
                   1684:   return 1000*((ms+999)/1000);
                   1685: #endif
                   1686: #endif
                   1687: #if OS_WIN
                   1688:   Sleep(ms);
                   1689:   return ms;
                   1690: #endif
                   1691: #if OS_MAC
                   1692:   UInt32 finalTicks;
                   1693:   UInt32 ticks = (((UInt32)ms+16)*3)/50;  /* 1/60 sec per tick */
                   1694:   Delay(ticks, &finalTicks);
                   1695:   return (int)((ticks*50)/3);
                   1696: #endif
                   1697: }
                   1698: 
                   1699: /*
                   1700: ** Static variables used for thread synchronization
                   1701: */
                   1702: static int inMutex = 0;
                   1703: #ifdef SQLITE_UNIX_THREADS
                   1704:   static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
                   1705: #endif
                   1706: #ifdef SQLITE_W32_THREADS
                   1707:   static CRITICAL_SECTION cs;
                   1708: #endif
                   1709: #ifdef SQLITE_MACOS_MULTITASKING
                   1710:   static MPCriticalRegionID criticalRegion;
                   1711: #endif
                   1712: 
                   1713: /*
                   1714: ** The following pair of routine implement mutual exclusion for
                   1715: ** multi-threaded processes.  Only a single thread is allowed to
                   1716: ** executed code that is surrounded by EnterMutex() and LeaveMutex().
                   1717: **
                   1718: ** SQLite uses only a single Mutex.  There is not much critical
                   1719: ** code and what little there is executes quickly and without blocking.
                   1720: */
                   1721: void sqliteOsEnterMutex(){
                   1722: #ifdef SQLITE_UNIX_THREADS
                   1723:   pthread_mutex_lock(&mutex);
                   1724: #endif
                   1725: #ifdef SQLITE_W32_THREADS
                   1726:   static int isInit = 0;
                   1727:   while( !isInit ){
                   1728:     static long lock = 0;
                   1729:     if( InterlockedIncrement(&lock)==1 ){
                   1730:       InitializeCriticalSection(&cs);
                   1731:       isInit = 1;
                   1732:     }else{
                   1733:       Sleep(1);
                   1734:     }
                   1735:   }
                   1736:   EnterCriticalSection(&cs);
                   1737: #endif
                   1738: #ifdef SQLITE_MACOS_MULTITASKING
                   1739:   static volatile int notInit = 1;
                   1740:   if( notInit ){
                   1741:     if( notInit == 2 ) /* as close as you can get to thread safe init */
                   1742:       MPYield();
                   1743:     else{
                   1744:       notInit = 2;
                   1745:       MPCreateCriticalRegion(&criticalRegion);
                   1746:       notInit = 0;
                   1747:     }
                   1748:   }
                   1749:   MPEnterCriticalRegion(criticalRegion, kDurationForever);
                   1750: #endif
                   1751:   assert( !inMutex );
                   1752:   inMutex = 1;
                   1753: }
                   1754: void sqliteOsLeaveMutex(){
                   1755:   assert( inMutex );
                   1756:   inMutex = 0;
                   1757: #ifdef SQLITE_UNIX_THREADS
                   1758:   pthread_mutex_unlock(&mutex);
                   1759: #endif
                   1760: #ifdef SQLITE_W32_THREADS
                   1761:   LeaveCriticalSection(&cs);
                   1762: #endif
                   1763: #ifdef SQLITE_MACOS_MULTITASKING
                   1764:   MPExitCriticalRegion(criticalRegion);
                   1765: #endif
                   1766: }
                   1767: 
                   1768: /*
                   1769: ** Turn a relative pathname into a full pathname.  Return a pointer
                   1770: ** to the full pathname stored in space obtained from sqliteMalloc().
                   1771: ** The calling function is responsible for freeing this space once it
                   1772: ** is no longer needed.
                   1773: */
                   1774: char *sqliteOsFullPathname(const char *zRelative){
                   1775: #if OS_UNIX
                   1776:   char *zFull = 0;
                   1777:   if( zRelative[0]=='/' ){
                   1778:     sqliteSetString(&zFull, zRelative, (char*)0);
                   1779:   }else{
                   1780:     char zBuf[5000];
                   1781:     zBuf[0] = 0;
                   1782:     sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
                   1783:                     (char*)0);
                   1784:   }
                   1785:   return zFull;
                   1786: #endif
                   1787: #if OS_WIN
                   1788:   char *zNotUsed;
                   1789:   char *zFull;
                   1790:   int nByte;
                   1791:   nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
                   1792:   zFull = sqliteMalloc( nByte );
                   1793:   if( zFull==0 ) return 0;
                   1794:   GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
                   1795:   return zFull;
                   1796: #endif
                   1797: #if OS_MAC
                   1798:   char *zFull = 0;
                   1799:   if( zRelative[0]==':' ){
                   1800:     char zBuf[_MAX_PATH+1];
                   1801:     sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
                   1802:                     (char*)0);
                   1803:   }else{
                   1804:     if( strchr(zRelative, ':') ){
                   1805:       sqliteSetString(&zFull, zRelative, (char*)0);
                   1806:     }else{
                   1807:     char zBuf[_MAX_PATH+1];
                   1808:       sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
                   1809:     }
                   1810:   }
                   1811:   return zFull;
                   1812: #endif
                   1813: }
                   1814: 
                   1815: /*
                   1816: ** The following variable, if set to a non-zero value, becomes the result
                   1817: ** returned from sqliteOsCurrentTime().  This is used for testing.
                   1818: */
                   1819: #ifdef SQLITE_TEST
                   1820: int sqlite_current_time = 0;
                   1821: #endif
                   1822: 
                   1823: /*
                   1824: ** Find the current time (in Universal Coordinated Time).  Write the
                   1825: ** current time and date as a Julian Day number into *prNow and
                   1826: ** return 0.  Return 1 if the time and date cannot be found.
                   1827: */
                   1828: int sqliteOsCurrentTime(double *prNow){
                   1829: #if OS_UNIX
                   1830:   time_t t;
                   1831:   time(&t);
                   1832:   *prNow = t/86400.0 + 2440587.5;
                   1833: #endif
                   1834: #if OS_WIN
                   1835:   FILETIME ft;
                   1836:   /* FILETIME structure is a 64-bit value representing the number of 
                   1837:      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
                   1838:   */
                   1839:   double now;
                   1840:   GetSystemTimeAsFileTime( &ft );
                   1841:   now = ((double)ft.dwHighDateTime) * 4294967296.0; 
                   1842:   *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
                   1843: #endif
                   1844: #ifdef SQLITE_TEST
                   1845:   if( sqlite_current_time ){
                   1846:     *prNow = sqlite_current_time/86400.0 + 2440587.5;
                   1847:   }
                   1848: #endif
                   1849:   return 0;
                   1850: }

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