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